mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Enable IPv6 for ESP32 Arduino, wifi and ethernet (#4865)
This commit is contained in:
		| @@ -118,6 +118,10 @@ void EthernetComponent::setup() { | ||||
|   ESPHL_ERROR_CHECK(err, "ETH event handler register error"); | ||||
|   err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &EthernetComponent::got_ip_event_handler, nullptr); | ||||
|   ESPHL_ERROR_CHECK(err, "GOT IP event handler register error"); | ||||
| #if LWIP_IPV6 | ||||
|   err = esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &EthernetComponent::got_ip6_event_handler, nullptr); | ||||
|   ESPHL_ERROR_CHECK(err, "GOT IP6 event handler register error"); | ||||
| #endif /* LWIP_IPV6 */ | ||||
|  | ||||
|   /* start Ethernet driver state machine */ | ||||
|   err = esp_eth_start(this->eth_handle_); | ||||
| @@ -160,6 +164,20 @@ void EthernetComponent::loop() { | ||||
|         this->state_ = EthernetComponentState::CONNECTING; | ||||
|         this->start_connect_(); | ||||
|       } | ||||
| #if LWIP_IPV6 | ||||
|       else if (this->got_ipv6_) { | ||||
|         esp_ip6_addr_t ip6_addr; | ||||
|         if (esp_netif_get_ip6_global(this->eth_netif_, &ip6_addr) == 0 && | ||||
|             esp_netif_ip6_get_addr_type(&ip6_addr) == ESP_IP6_ADDR_IS_GLOBAL) { | ||||
|           ESP_LOGCONFIG(TAG, "IPv6 Addr (Global): " IPV6STR, IPV62STR(ip6_addr)); | ||||
|         } else { | ||||
|           esp_netif_get_ip6_linklocal(this->eth_netif_, &ip6_addr); | ||||
|           ESP_LOGCONFIG(TAG, " IPv6: " IPV6STR, IPV62STR(ip6_addr)); | ||||
|         } | ||||
|  | ||||
|         this->got_ipv6_ = false; | ||||
|       } | ||||
| #endif /* LWIP_IPV6 */ | ||||
|       break; | ||||
|   } | ||||
| } | ||||
| @@ -254,6 +272,15 @@ void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_b | ||||
|   ESP_LOGV(TAG, "[Ethernet event] ETH Got IP (num=%" PRId32 ")", event_id); | ||||
| } | ||||
|  | ||||
| #if LWIP_IPV6 | ||||
| void EthernetComponent::got_ip6_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, | ||||
|                                               void *event_data) { | ||||
|   ESP_LOGV(TAG, "[Ethernet event] ETH Got IP6 (num=%d)", event_id); | ||||
|   global_eth_component->got_ipv6_ = true; | ||||
|   global_eth_component->ipv6_count_ += 1; | ||||
| } | ||||
| #endif /* LWIP_IPV6 */ | ||||
|  | ||||
| void EthernetComponent::start_connect_() { | ||||
|   this->connect_begin_ = millis(); | ||||
|   this->status_set_warning(); | ||||
| @@ -316,6 +343,12 @@ void EthernetComponent::start_connect_() { | ||||
|     if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) { | ||||
|       ESPHL_ERROR_CHECK(err, "DHCPC start error"); | ||||
|     } | ||||
| #if LWIP_IPV6 | ||||
|     err = esp_netif_create_ip6_linklocal(this->eth_netif_); | ||||
|     if (err != ESP_OK) { | ||||
|       ESPHL_ERROR_CHECK(err, "IPv6 local failed"); | ||||
|     } | ||||
| #endif /* LWIP_IPV6 */ | ||||
|   } | ||||
|  | ||||
|   this->connect_begin_ = millis(); | ||||
| @@ -343,6 +376,19 @@ void EthernetComponent::dump_connect_params_() { | ||||
|   ESP_LOGCONFIG(TAG, "  DNS2: %s", network::IPAddress(dns_ip2->addr).str().c_str()); | ||||
| #endif | ||||
|  | ||||
| #if LWIP_IPV6 | ||||
|   if (this->ipv6_count_ > 0) { | ||||
|     esp_ip6_addr_t ip6_addr; | ||||
|     esp_netif_get_ip6_linklocal(this->eth_netif_, &ip6_addr); | ||||
|     ESP_LOGCONFIG(TAG, " IPv6: " IPV6STR, IPV62STR(ip6_addr)); | ||||
|  | ||||
|     if (esp_netif_get_ip6_global(this->eth_netif_, &ip6_addr) == 0 && | ||||
|         esp_netif_ip6_get_addr_type(&ip6_addr) == ESP_IP6_ADDR_IS_GLOBAL) { | ||||
|       ESP_LOGCONFIG(TAG, "IPv6 Addr (Global): " IPV6STR, IPV62STR(ip6_addr)); | ||||
|     } | ||||
|   } | ||||
| #endif /* LWIP_IPV6 */ | ||||
|  | ||||
|   esp_err_t err; | ||||
|  | ||||
|   uint8_t mac[6]; | ||||
|   | ||||
| @@ -65,6 +65,9 @@ class EthernetComponent : public Component { | ||||
|  protected: | ||||
|   static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); | ||||
|   static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); | ||||
| #if LWIP_IPV6 | ||||
|   static void got_ip6_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); | ||||
| #endif /* LWIP_IPV6 */ | ||||
|  | ||||
|   void start_connect_(); | ||||
|   void dump_connect_params_(); | ||||
| @@ -83,6 +86,10 @@ class EthernetComponent : public Component { | ||||
|  | ||||
|   bool started_{false}; | ||||
|   bool connected_{false}; | ||||
| #if LWIP_IPV6 | ||||
|   bool got_ipv6_{false}; | ||||
|   uint8_t ipv6_count_{0}; | ||||
| #endif /* LWIP_IPV6 */ | ||||
|   EthernetComponentState state_{EthernetComponentState::STOPPED}; | ||||
|   uint32_t connect_begin_; | ||||
|   esp_netif_t *eth_netif_{nullptr}; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| from esphome.core import CORE | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components.esp32 import add_idf_sdkconfig_option | ||||
| @@ -14,8 +15,8 @@ IPAddress = network_ns.class_("IPAddress") | ||||
|  | ||||
| CONFIG_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.SplitDefault(CONF_ENABLE_IPV6, esp32_idf=False): cv.All( | ||||
|             cv.only_with_esp_idf, cv.boolean | ||||
|         cv.SplitDefault(CONF_ENABLE_IPV6, esp32=False): cv.All( | ||||
|             cv.only_on_esp32, cv.boolean | ||||
|         ), | ||||
|     } | ||||
| ) | ||||
| @@ -23,7 +24,12 @@ CONFIG_SCHEMA = cv.Schema( | ||||
|  | ||||
| async def to_code(config): | ||||
|     if CONF_ENABLE_IPV6 in config: | ||||
|         if CORE.using_esp_idf: | ||||
|             add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) | ||||
|             add_idf_sdkconfig_option( | ||||
|                 "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] | ||||
|             ) | ||||
|         else: | ||||
|             if config[CONF_ENABLE_IPV6]: | ||||
|                 cg.add_build_flag("-DCONFIG_LWIP_IPV6") | ||||
|                 cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") | ||||
|   | ||||
| @@ -485,6 +485,9 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ | ||||
|       buf[it.ssid_len] = '\0'; | ||||
|       ESP_LOGV(TAG, "Event: Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf, | ||||
|                format_mac_addr(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode)); | ||||
| #if LWIP_IPV6 | ||||
|       WiFi.enableIpV6(); | ||||
| #endif /* LWIP_IPV6 */ | ||||
|  | ||||
|       break; | ||||
|     } | ||||
| @@ -547,6 +550,13 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ | ||||
|       s_sta_connecting = false; | ||||
|       break; | ||||
|     } | ||||
| #if LWIP_IPV6 | ||||
|     case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: { | ||||
|       auto it = info.got_ip6.ip6_info; | ||||
|       ESP_LOGV(TAG, "Got IPv6 address=" IPV6STR, IPV62STR(it.ip)); | ||||
|       break; | ||||
|     } | ||||
| #endif /* LWIP_IPV6 */ | ||||
|     case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: { | ||||
|       ESP_LOGV(TAG, "Event: Lost IP"); | ||||
|       break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user