arduino-esp32 icon indicating copy to clipboard operation
arduino-esp32 copied to clipboard

IPv6 Global Link Support

Open altmannmarcelo opened this issue 2 years ago • 8 comments

Board

ESP32S2

Device Description

ESP-s2-saola-1

Hardware Configuration

No

Version

v2.0.2

IDE Name

Arduino IDE

Operating System

Ubuntu 20.04

Flash frequency

NA

PSRAM enabled

yes

Upload speed

NA

Description

Based on https://github.com/espressif/arduino-esp32/issues/1261 IPv6 support on arduino-esp32 is as complete as ESP-IDF and the needed configuration should be exposed via menuconfig.

On current ESP-IDF version, I can configure sample projects to receive IPv6 either via SLAAC or DCHP6 via idf.py menuconfig -> Component config ---> LWIP ---> Enable IPV6 stateless address autoconfiguration (SLAAC)

From my understanding this is what was missing for this project to have Global IPv6 support.

image

image

Sketch

NA

Debug Message

NA

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.

altmannmarcelo avatar Apr 25 '22 18:04 altmannmarcelo

@altmannmarcelo Please check merged PR which can solve your issue.

https://github.com/espressif/esp32-arduino-lib-builder/pull/67

It will be available in next release 2.0.4.

VojtechBartoska avatar Jun 14 '22 13:06 VojtechBartoska

@altmannmarcelo Have you been able to retest this under 2.0.4?

VojtechBartoska avatar Jul 26 '22 13:07 VojtechBartoska

@altmannmarcelo Have you been able to retest this under 2.0.4?

With 2.0.4, I can get "global IPv6 address for ESP32". But i faced problem on communication with IPv6.

Using following simply code, IPv6 comunication is OK between two ESP8266 board.

Send:

m_WiFiUDP.beginPacket("240e:3a1:2e6:ee6:42f5:20ff:fe30:a6b3", 5050);
m_WiFiUDP.write((const char*)&TestStruData, sizeof(tTestStruData));
m_WiFiUDP.endPacket(); 

Receive

m_WiFiUDP.parsePacket(); 
unsigned int UdpAvailable = m_WiFiUDP.available();
printf("m_WiFiUDP.available() = %d\r\n",UdpAvailable);

But when I use ESP32 as the Receiver. It will never have available bytes from IPv6. (IPv4 is OK).

fryefryefrye avatar Jul 31 '22 13:07 fryefryefrye

Hi @VojtechBartoska . I still don't see a call to esp_netif_get_ip6_global been exposed where we can check which global IPv6 has been assigned. For example, for local IPv6 we have localIPv6 that calls esp_netif_get_ip6_linklocal. So I think global ipv6 link is still not possible.

altmannmarcelo avatar Aug 02 '22 18:08 altmannmarcelo

ok, extending WiFiSTA.h and WiFiSTA.cpp to call esp_netif_get_ip6_global makes is possible to get an IPv6 global address. and I can ping it:

15:20:55.109 -> STA IPv6: xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130

$ ping xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130
PING xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130(xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130) 56 data bytes
64 bytes from xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130: icmp_seq=1 ttl=255 time=1.87 ms
64 bytes from xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130: icmp_seq=2 ttl=255 time=1.75 ms
64 bytes from xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130: icmp_seq=3 ttl=255 time=1.92 ms
64 bytes from xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130: icmp_seq=4 ttl=255 time=4.77 ms
64 bytes from xxx:xxx:80eb:xxx:7edf:a1ff:fe3d:7130: icmp_seq=5 ttl=255 time=1.83 ms

Will submit a PR to expose the info via the API.

@fryefryefrye can you share the code you used for testing?

altmannmarcelo avatar Aug 02 '22 18:08 altmannmarcelo

seems like @fryefryefrye already submitted it at #7065

altmannmarcelo avatar Aug 02 '22 18:08 altmannmarcelo

The following code is working between 2 ESP8266 boards. I will post ESP32 code later.

#include<ESP8266WiFi.h>
#include<WiFiUdp.h>
#include<ESP8266mDNS.h>
#include<ESP8266WiFiMulti.h>

const char* ssid = "frye_v6";
const char* password = "12345678";
WiFiUDP m_WiFiUDP;


String ipv4_ip, ipv4_subnet_mask, ipv4_gateway,
ipv6_ip, ipv6_retain, ip_dns1, ip_dns2;

void UpdateIpv6Info()
{
	for (int data_ip_dns = 0; data_ip_dns < DNS_MAX_SERVERS; data_ip_dns++)
	{
		IPAddress data_dns = WiFi.dnsIP(data_ip_dns);
		if (data_dns.isSet())
		{
			switch (data_ip_dns)
			{
			case false: ip_dns1 = data_dns.toString().c_str(); break;
			case true: ip_dns2 = data_dns.toString().c_str(); break;
			}
		}
	}
	for (auto data_ip : addrList)
	{
		if (data_ip.isV6() && data_ip.isLocal() == false)
		{
			ipv6_ip = data_ip.toString().c_str();
		}

		if (data_ip.isV6() && data_ip.isLocal())
			ipv6_retain = data_ip.toString().c_str();
		if (data_ip.isV6() == false && data_ip.isLocal() == false)
			ipv4_ip = data_ip.toString().c_str();
		if (data_ip.isLegacy())
		{
			ipv4_subnet_mask = data_ip.netmask().toString().c_str();
			ipv4_gateway = data_ip.gw().toString().c_str();
		}
	}

	//Serial.println(F("------------------------------"));
	//Serial.printf("IP Info\r\n");
	//Serial.printf("IPV4\taddress: %s\r\n", ipv4_ip.c_str());
	//Serial.printf("IPV4\tmask: %s\r\n", ipv4_subnet_mask.c_str());
	//Serial.printf("IPV4\tgate: %s\r\n", ipv4_gateway.c_str());
	//Serial.printf("IPV6\taddress: %s\r\n", ipv6_ip.c_str());
	//Serial.printf("IPV6\tretain: %s\r\n", ipv6_retain.c_str());
	//Serial.printf("DNS1: \t %s\r\n", ip_dns1.c_str());
	//Serial.printf("DNS2: \t %s\r\n", ip_dns2.c_str());
	//Serial.println(F("------------------------------"));

//IP Info
//IPV4    address: 192.168.0.4
//IPV4    mask: 255.255.255.0
//IPV4    gate: 192.168.0.16
//IPV6    address: 240e:3a1:2c4:6485:42f5:20ff:fe30:a6b3
//IPV6    retain: fe80::42f5:20ff:fe30:a6b3
//DNS1:    192.168.0.16
//DNS2:    fe80::96e9:eeff:fe3a:6140

}

void setup() 
{                      
	Serial.begin(115200);

	WiFi.disconnect();
	WiFi.mode(WIFI_STA);

	Serial.print("Is connection routing, please wait");  
	WiFi.begin(ssid, password);
	Serial.println("\nConnecting to WiFi");

	while (WiFi.status() != WL_CONNECTED) {  
		Serial.print("."); 
		delay(1000);
	}

	Serial.println("Ready");
	Serial.print("IPv4 address: ");
	Serial.println(WiFi.localIP());

	Serial.println("\nWaiting for ipv6 address");
	while (ipv6_ip == "") {
		Serial.print(".");
		UpdateIpv6Info();
		delay(1000);
	}
	Serial.printf("\r\nIPv6 address: %s\r\n", ipv6_ip.c_str());
	Serial.println("");

	m_WiFiUDP.begin(5050);
}

void loop() 
{
	//Recv UDP
	m_WiFiUDP.parsePacket();
	unsigned int UdpAvailable = m_WiFiUDP.available();
	if (UdpAvailable != 0)
	{
		printf("m_WiFiUDP.available() = %d\r\n", UdpAvailable);
		//m_WiFiUDP.read((char*)&tempTestStruCommand, sizeof(tTestStruCommand));
		m_WiFiUDP.flush();
	}


	//Send UDP every 1s
	unsigned long TestData = 1;

	static unsigned long LastMillis = 0;
	unsigned long CurrentMillis = millis();
	if (CurrentMillis - LastMillis > 1000)
	{
		LastMillis = CurrentMillis;
		m_WiFiUDP.beginPacket("240e:3a1:2c4:6485:42f5:20ff:fe30:a6b3", 5050);
		m_WiFiUDP.write((const char*)&TestData, sizeof(unsigned long));
		m_WiFiUDP.endPacket();
	}
}

fryefryefrye avatar Aug 04 '22 08:08 fryefryefrye

Here is the test code for ESP32 to comunication using UDP via ipv6. But it's not working.

#include <WiFi.h>
#include <WiFiGeneric.h>

const char* ssid = "frye_v6";
const char* password = "12345678";
WiFiUDP m_WiFiUDP;

esp_netif_t* get_esp_interface_netif(esp_interface_t interface);

bool ipv6OK = false;

void WiFiEvent(WiFiEvent_t event) {
	switch (event) {
	case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
		Serial.print("STA IPv6: ");
		Serial.println(WiFi.localIPv6());

		esp_ip6_addr_t addr;
		esp_netif_get_ip6_global(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr);
		Serial.print("STA global IPv6: ");
		Serial.println(IPv6Address(addr.addr));

		//Serial.print("STA Global IPv6: ");
		//Serial.println(WiFi.globalIPv6());

		ipv6OK = true;
		m_WiFiUDP.begin(5050);

		break;

	default:
		break;
	}
}

void setup() 
{                      
	Serial.begin(115200);

	WiFi.disconnect();
	WiFi.onEvent(WiFiEvent);
	WiFi.mode(WIFI_MODE_APSTA);

	Serial.print("Is connection routing, please wait");  
	WiFi.begin(ssid, password);
	Serial.println("\nConnecting to WiFi");

	while (WiFi.status() != WL_CONNECTED) {  
		Serial.print("."); 
		delay(1000);
	}

	WiFi.enableIpV6();

	Serial.println("Ready");
	Serial.print("IPv4 address: ");
	Serial.println(WiFi.localIP());
	Serial.println("Wait IPv6 address");
}

void loop() 
{
	if (ipv6OK)
	{
		//Recv UDP
		m_WiFiUDP.parsePacket();
		unsigned int UdpAvailable = m_WiFiUDP.available();
		if (UdpAvailable != 0)
		{
			printf("m_WiFiUDP.available() = %d\r\n", UdpAvailable);
			//m_WiFiUDP.read((char*)&tempTestStruCommand, sizeof(tTestStruCommand));
			m_WiFiUDP.flush();
		}


		//Send UDP every 1s
		unsigned long TestData = 1;

		static unsigned long LastMillis = 0;
		unsigned long CurrentMillis = millis();
		if (CurrentMillis - LastMillis > 1000)
		{
			LastMillis = CurrentMillis;
			m_WiFiUDP.beginPacket("2409:8920:270:65a5:a220:a6ff:fe21:af77", 5050);
			m_WiFiUDP.write((const uint8_t*)&TestData, sizeof(unsigned long));
			m_WiFiUDP.endPacket();
		}
	}
}

fryefryefrye avatar Aug 06 '22 14:08 fryefryefrye

I need support for IPv6 too.

digits122 avatar May 16 '23 12:05 digits122

How looks this issue? IPv6 is almost everywhere and here it missing global addresses. I just extended wifi sta with global getter, so I can get global IP already

petrkr avatar May 23 '23 19:05 petrkr

Someone knows about updates for this issue ?

brskt-dev avatar Jun 30 '23 11:06 brskt-dev

@brskt-dev sorted for development, will be part of upcoming major release 3.0.0

VojtechBartoska avatar Jun 30 '23 11:06 VojtechBartoska

@brskt-dev sorted for development, will be part of upcoming major release 3.0.0

Do we have tentative time when this new release will be released ? Where I am, some major companies started giving routers that supports IPv6 only.

dharmikP17 avatar Jul 07 '23 09:07 dharmikP17

@dharmikP17

You can see the realese roadmap on the link below. I didn't find anything about dates, but at least we can see the progress of feats/fix... https://github.com/orgs/espressif/projects/3/views/14

brskt-dev avatar Jul 07 '23 10:07 brskt-dev

Seems this was covered by https://github.com/espressif/arduino-esp32/pull/9016. I am closing this ticket, if needed you can reopen.

VojtechBartoska avatar Feb 20 '24 15:02 VojtechBartoska