espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.33k stars 7.36k forks source link

IPv6 Global Link Support #6626

Closed altmannmarcelo closed 7 months ago

altmannmarcelo commented 2 years ago

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

VojtechBartoska commented 2 years ago

@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 commented 2 years ago

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

fryefryefrye commented 2 years ago

@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).

altmannmarcelo commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

seems like @fryefryefrye already submitted it at #7065

fryefryefrye commented 2 years ago

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 commented 2 years ago

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();
        }
    }
}
digits122 commented 1 year ago

I need support for IPv6 too.

petrkr commented 1 year ago

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

brskt-dev commented 1 year ago

Someone knows about updates for this issue ?

VojtechBartoska commented 1 year ago

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

dharmikP17 commented 1 year ago

@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.

brskt-dev commented 1 year ago

@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

VojtechBartoska commented 7 months ago

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