mirror of
https://github.com/esphome/esphome.git
synced 2025-10-28 21:53:48 +00:00
Improve dualstack and IPv6 support (#5449)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
@@ -119,10 +119,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 ENABLE_IPV6
|
||||
#if USE_NETWORK_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 /* ENABLE_IPV6 */
|
||||
ESPHL_ERROR_CHECK(err, "GOT IPv6 event handler register error");
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
/* start Ethernet driver state machine */
|
||||
err = esp_eth_start(this->eth_handle_);
|
||||
@@ -165,20 +165,6 @@ void EthernetComponent::loop() {
|
||||
this->state_ = EthernetComponentState::CONNECTING;
|
||||
this->start_connect_();
|
||||
}
|
||||
#if ENABLE_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 /* ENABLE_IPV6 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -234,10 +220,28 @@ float EthernetComponent::get_setup_priority() const { return setup_priority::WIF
|
||||
|
||||
bool EthernetComponent::can_proceed() { return this->is_connected(); }
|
||||
|
||||
network::IPAddress EthernetComponent::get_ip_address() {
|
||||
network::IPAddresses EthernetComponent::get_ip_addresses() {
|
||||
network::IPAddresses addresses;
|
||||
esp_netif_ip_info_t ip;
|
||||
esp_netif_get_ip_info(this->eth_netif_, &ip);
|
||||
return network::IPAddress(&ip.ip);
|
||||
esp_err_t err = esp_netif_get_ip_info(this->eth_netif_, &ip);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "esp_netif_get_ip_info failed: %s", esp_err_to_name(err));
|
||||
// TODO: do something smarter
|
||||
// return false;
|
||||
} else {
|
||||
addresses[0] = network::IPAddress(&ip.ip);
|
||||
}
|
||||
#if USE_NETWORK_IPV6
|
||||
struct esp_ip6_addr if_ip6s[CONFIG_LWIP_IPV6_NUM_ADDRESSES];
|
||||
uint8_t count = 0;
|
||||
count = esp_netif_get_all_ip6(this->eth_netif_, if_ip6s);
|
||||
assert(count <= CONFIG_LWIP_IPV6_NUM_ADDRESSES);
|
||||
for (int i = 0; i < count; i++) {
|
||||
addresses[i + 1] = network::IPAddress(&if_ip6s[i]);
|
||||
}
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
void EthernetComponent::eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event, void *event_data) {
|
||||
@@ -269,20 +273,33 @@ void EthernetComponent::eth_event_handler(void *arg, esp_event_base_t event_base
|
||||
|
||||
void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id,
|
||||
void *event_data) {
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
||||
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP " IPSTR, IP2STR(&ip_info->ip));
|
||||
global_eth_component->got_ipv4_address_ = true;
|
||||
#if USE_NETWORK_IPV6
|
||||
global_eth_component->connected_ = global_eth_component->ipv6_count_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT;
|
||||
#else
|
||||
global_eth_component->connected_ = true;
|
||||
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP (num=%" PRId32 ")", event_id);
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
}
|
||||
|
||||
#if ENABLE_IPV6
|
||||
#if USE_NETWORK_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=%" PRId32 ")", event_id);
|
||||
global_eth_component->got_ipv6_ = true;
|
||||
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *) event_data;
|
||||
ESP_LOGV(TAG, "[Ethernet event] ETH Got IPv6: " IPV6STR, IPV62STR(event->ip6_info.ip));
|
||||
global_eth_component->ipv6_count_ += 1;
|
||||
global_eth_component->connected_ =
|
||||
global_eth_component->got_ipv4_address_ && (global_eth_component->ipv6_count_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT);
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
void EthernetComponent::start_connect_() {
|
||||
global_eth_component->got_ipv4_address_ = false;
|
||||
#if USE_NETWORK_IPV6
|
||||
global_eth_component->ipv6_count_ = 0;
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
this->connect_begin_ = millis();
|
||||
this->status_set_warning();
|
||||
|
||||
@@ -334,12 +351,12 @@ void EthernetComponent::start_connect_() {
|
||||
if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) {
|
||||
ESPHL_ERROR_CHECK(err, "DHCPC start error");
|
||||
}
|
||||
#if ENABLE_IPV6
|
||||
#if USE_NETWORK_IPV6
|
||||
err = esp_netif_create_ip6_linklocal(this->eth_netif_);
|
||||
if (err != ESP_OK) {
|
||||
ESPHL_ERROR_CHECK(err, "IPv6 local failed");
|
||||
ESPHL_ERROR_CHECK(err, "Enable IPv6 link local failed");
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
}
|
||||
|
||||
this->connect_begin_ = millis();
|
||||
@@ -362,18 +379,15 @@ void EthernetComponent::dump_connect_params_() {
|
||||
ESP_LOGCONFIG(TAG, " DNS1: %s", network::IPAddress(dns_ip1).str().c_str());
|
||||
ESP_LOGCONFIG(TAG, " DNS2: %s", network::IPAddress(dns_ip2).str().c_str());
|
||||
|
||||
#if ENABLE_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));
|
||||
}
|
||||
#if USE_NETWORK_IPV6
|
||||
struct esp_ip6_addr if_ip6s[CONFIG_LWIP_IPV6_NUM_ADDRESSES];
|
||||
uint8_t count = 0;
|
||||
count = esp_netif_get_all_ip6(this->eth_netif_, if_ip6s);
|
||||
assert(count <= CONFIG_LWIP_IPV6_NUM_ADDRESSES);
|
||||
for (int i = 0; i < count; i++) {
|
||||
ESP_LOGCONFIG(TAG, " IPv6: " IPV6STR, IPV62STR(if_ip6s[i]));
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
esp_err_t err;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user