Skip to content
31 changes: 30 additions & 1 deletion wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,21 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
#ifdef WLED_USE_ETHERNET
JsonObject ethernet = doc[F("eth")];
CJSON(ethernetType, ethernet["type"]);
// NOTE: Ethernet configuration takes priority over other use of pins
#if defined(ARDUINO_ARCH_ESP32)
// AI: deserialize ethernet static IP configuration.
JsonArray eth_ip = ethernet[F("eip")];
JsonArray eth_gw = ethernet[F("egw")];
JsonArray eth_sn = ethernet[F("esn")];
if (!eth_ip.isNull()) {
for (size_t i = 0; i < 4; i++) {
CJSON(ethStaticIP[i], eth_ip[i]);
CJSON(ethStaticGW[i], eth_gw[i]);
CJSON(ethStaticSN[i], eth_sn[i]);
}
}
// AI: deserialize primary network interface selection.
CJSON(ethPrimaryInterface, ethernet[F("epi")]);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
#endif
initEthernet();
#endif
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Expand Down Expand Up @@ -935,6 +949,21 @@ void serializeConfig(JsonObject root) {
break;
}
}
// AI: serialize ethernet static IP configuration.
// Stored as 4-element JSON arrays, one byte per octet, consistent
// with the WiFi static IP serialisation pattern in nw.ins[n].ip/gw/sn.
// Only written when an ethernet board type is configured.
JsonArray eth_ip = ethernet.createNestedArray(F("eip"));
JsonArray eth_gw = ethernet.createNestedArray(F("egw"));
JsonArray eth_sn = ethernet.createNestedArray(F("esn"));
for (size_t i = 0; i < 4; i++) {
eth_ip.add(ethStaticIP[i]);
eth_gw.add(ethStaticGW[i]);
eth_sn.add(ethStaticSN[i]);
}
// AI: serialize primary network interface selection.
// false = WiFi is primary, true = Ethernet is primary.
ethernet[F("epi")] = ethPrimaryInterface;
#endif

JsonObject hw = root.createNestedObject(F("hw"));
Expand Down
46 changes: 42 additions & 4 deletions wled00/data/settings_wifi.htm
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,14 @@
Identity:<br><input type="text" id="EI${i}" name="EI${i}" maxlength="64" value="${ident}"><br>
</div>`;
}
// AI: removed "Also used by Ethernet" note from WiFi static IP label
// WiFi and Ethernet now have independent IP configurations
var b = `<div id="net${i}"><hr class="sml">
Network name (SSID${i==0?", empty to not connect":""}):<br><input type="text" id="CS${i}" name="CS${i}" maxlength="32" value="${ssid}" ${i>0?"required":""}><br>
${encryptionTypeField}
Network password:<br><input type="password" name="PW${i}" maxlength="64" value="${pass}"><br>
BSSID (optional):<br><input type="text" id="BS${i}" name="BS${i}" maxlength="12" value="${bssid}"><br>
Static IP (leave at 0.0.0.0 for DHCP)${i==0?"<br>Also used by Ethernet":""}:<br>
Static IP (leave at 0.0.0.0 for DHCP):<br>
<input name="IP${i}0" type="number" class="s" min="0" max="255" value="${ip&0xFF}" required>.<input name="IP${i}1" type="number" class="s" min="0" max="255" value="${(ip>>8)&0xFF}" required>.<input name="IP${i}2" type="number" class="s" min="0" max="255" value="${(ip>>16)&0xFF}" required>.<input name="IP${i}3" type="number" class="s" min="0" max="255" value="${(ip>>24)&0xFF}" required><br>
Static gateway:<br>
<input name="GW${i}0" type="number" class="s" min="0" max="255" value="${gw&0xFF}" required>.<input name="GW${i}1" type="number" class="s" min="0" max="255" value="${(gw>>8)&0xFF}" required>.<input name="GW${i}2" type="number" class="s" min="0" max="255" value="${(gw>>16)&0xFF}" required>.<input name="GW${i}3" type="number" class="s" min="0" max="255" value="${(gw>>24)&0xFF}" required><br>
Expand Down Expand Up @@ -166,6 +168,8 @@
function tE() {
// keep the hidden input with MAC addresses, only toggle visibility of the list UI
gId('rlc').style.display = d.Sf.RE.checked ? 'block' : 'none';
// AI: also refresh ethernet IP section visibility on page init
toggleEthIP();
}
// reset remotes: initialize empty list (called from xml.cpp)
function rstR() {
Expand Down Expand Up @@ -207,6 +211,18 @@
}
}

// AI: toggleEthIP() shows or hides the Ethernet static IP configuration
// section based on whether an ethernet board type is selected.
// Called on page init (via tE) and on ethernet type dropdown change.
function toggleEthIP() {
const ethSelect = d.Sf.ETH;
if (!ethSelect) return;
const ethIpSection = gId('ethip');
if (!ethIpSection) return;
// AI: value "0" means "None" - no ethernet board selected, hide IP config
ethIpSection.style.display = (ethSelect.value !== "0") ? 'block' : 'none';
}

</script>
</head>
<body>
Expand All @@ -228,7 +244,8 @@ <h3>Wireless network</h3>
</div>
<div class="sec" id="ethd">
<h3>Ethernet Type</h3>
<select name="ETH">
<!-- AI: added onchange="toggleEthIP()" to show/hide ethernet IP section -->
<select name="ETH" onchange="toggleEthIP()">
<option value="0">None</option>
<option value="6">IoTorero/ESP32Deux/RGB2Go</option>
<option value="9">ABC! WLED V43 & compatible</option>
Expand All @@ -246,15 +263,36 @@ <h3>Ethernet Type</h3>
<option value="1">WT32-ETH01</option>
<option value="13">Gledopto</option>
</select><br><br>
</div>
<!-- AI: below section was generated by an AI -->
<div id="ethip" style="display:none;">
<h3>Ethernet IP Configuration</h3>
Static IP (leave at 0.0.0.0 for DHCP):<br>
<input name="EIP0" type="number" class="s" min="0" max="255" value="0" required>.<input name="EIP1" type="number" class="s" min="0" max="255" value="0" required>.<input name="EIP2" type="number" class="s" min="0" max="255" value="0" required>.<input name="EIP3" type="number" class="s" min="0" max="255" value="0" required><br>
Static gateway (leave at 0.0.0.0 for no gateway):<br>
<input name="EGW0" type="number" class="s" min="0" max="255" value="0" required>.<input name="EGW1" type="number" class="s" min="0" max="255" value="0" required>.<input name="EGW2" type="number" class="s" min="0" max="255" value="0" required>.<input name="EGW3" type="number" class="s" min="0" max="255" value="0" required><br>
Static subnet mask:<br>
<input name="ESN0" type="number" class="s" min="0" max="255" value="255" required>.<input name="ESN1" type="number" class="s" min="0" max="255" value="255" required>.<input name="ESN2" type="number" class="s" min="0" max="255" value="255" required>.<input name="ESN3" type="number" class="s" min="0" max="255" value="0" required><br><br>

<hr class="sml">

<!-- AI: primary network interface selector shown when ethernet board is selected -->
<h3>Primary Network Interface</h3>
Select the primary network WLED should use for internet and for access to network services like NTP, MQTT, etc.<br>
<input type="radio" name="EPI" value="0" checked> WiFi
&nbsp;&lt;--&gt;&nbsp;
<input type="radio" name="EPI" value="1"> Ethernet<br><br>
<!-- AI: end -->
</div>
</div>
<div class="sec">
<h3>DNS & mDNS</h3>
DNS server address:<br>
<input name="D0" type="number" class="s" min="0" max="255" required>.<input name="D1" type="number" class="s" min="0" max="255" required>.<input name="D2" type="number" class="s" min="0" max="255" required>.<input name="D3" type="number" class="s" min="0" max="255" required><br>
<br>
mDNS address (leave empty for no mDNS):<br>
http:// <input type="text" name="CM" maxlength="32"> .local<br>
Client IP: <span class="sip"> Not connected </span> <br>
<!-- AI: updated label to reflect dual interface operation -->
Active IP(s): <span class="sip"> Not connected </span>
</div>
<div class="sec">
<h3>Configure Access Point</h3>
Expand Down
7 changes: 7 additions & 0 deletions wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,13 @@ void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rs

//network.cpp
bool initEthernet(); // result is informational
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
bool initEthernet();
// AI: sets lwIP primary network interface based on ethPrimaryInterface
// by enabling wled to be dual-homed we need to be deterministic about which interface
// wled uses for outgoing connections to minimise asyncronous routing issues.
void setPrimaryNetworkInterface();
#endif
int getSignalQuality(int rssi);
void fillMAC2Str(char *str, const uint8_t *mac);
void fillStr2MAC(uint8_t *mac, const char *str);
Expand Down
112 changes: 104 additions & 8 deletions wled00/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@


#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
#include "lwip/netif.h" // AI: required for netif_set_default() and netif_list
#include "lwip/tcpip.h" // AI: required for LOCK_TCPIP_CORE/UNLOCK_TCPIP_CORE
// The following six pins are neither configurable nor
// can they be re-assigned through IOMUX / GPIO matrix.
// See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit-v1.1.html#ip101gri-phy-interface
Expand Down Expand Up @@ -274,18 +276,93 @@ bool initEthernet()
}

// https://github.com/wled/WLED/issues/5247
if (multiWiFi[0].staticIP != (uint32_t)0x00000000 && multiWiFi[0].staticGW != (uint32_t)0x00000000) {
ETH.config(multiWiFi[0].staticIP, multiWiFi[0].staticGW, multiWiFi[0].staticSN, dnsAddress);
// AI: apply ethernet static IP configuration using the new dedicated
// ethernet IP variables (ethStaticIP, ethStaticGW, ethStaticSN) rather than
// sharing the first WiFi network's static IP config as was previously done.
// ethStaticIP of 0.0.0.0 means use DHCP for ethernet.
// Gateway of 0.0.0.0 is valid — means no default route via ethernet,
// lwIP will only install a subnet route for the ethernet interface.
if ((uint32_t)ethStaticIP != 0x00000000) {
// AI: always pass the configured gateway to ETH.config().
// Default route selection between interfaces is handled by netif_set_default()
// in setPrimaryNetworkInterface(). Gateway of 0.0.0.0 is explicitly supported
// for users who want ethernet as a stub interface with no onward routing.
ETH.config(ethStaticIP, ethStaticGW, ethStaticSN, dnsAddress);
DEBUG_PRINTF_P(PSTR("initE: Static IP configured. IP=%d.%d.%d.%d GW=%d.%d.%d.%d PNI=%s\n"),
ethStaticIP[0], ethStaticIP[1], ethStaticIP[2], ethStaticIP[3],
ethStaticGW[0], ethStaticGW[1], ethStaticGW[2], ethStaticGW[3],
ethPrimaryInterface ? "ETH" : "WiFi");
} else {
// AI: no static IP configured, use DHCP for ethernet
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
DEBUG_PRINTLN(F("initE: DHCP configured for ethernet"));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

successfullyConfiguredEthernet = true;
DEBUG_PRINTLN(F("initE: *** Ethernet successfully configured! ***"));
return true;
}
#endif

// AI: setPrimaryNetworkInterface() explicitly sets the lwIP primary
// network interface based on the user's ethPrimaryInterface selection.
// Directly tells lwIP which netif to use for outbound traffic, resolving
// asymmetric routing issues where reply packets were routed out the wrong
// interface when both WiFi and Ethernet are active simultaneously.
// Interfaces are identified by name prefix ('en'=ethernet, 'st'=WiFi STA)
// which works correctly for both static IP and DHCP configurations.
// Called from multiple network events to ensure it fires after whichever
// interface comes up last.

// AI: below section was generated by an AI
void setPrimaryNetworkInterface() {
struct netif *netif_iter;
struct netif *target = nullptr;
struct netif *fallback = nullptr;

// AI: interface name prefixes in arduino-esp32 IDF V4 (Tasmota platform):
// 'en' = ethernet, 'st' = WiFi STA. Validated on IDF 4.4.8.
const char *targetName = ethPrimaryInterface ?
"en" :
"st";

// AI: acquire lwIP TCP/IP core lock before accessing netif_list
// and calling netif_set_default() to avoid thread-safety assertions
LOCK_TCPIP_CORE();

for (netif_iter = netif_list; netif_iter != NULL; netif_iter = netif_iter->next) {
if (!netif_is_up(netif_iter) || netif_iter->ip_addr.u_addr.ip4.addr == 0) continue;
const bool isPreferred = (netif_iter->name[0] == targetName[0] &&
netif_iter->name[1] == targetName[1]);
if (isPreferred) {
Comment on lines +322 to +336
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🌐 Web query:

For Arduino-ESP32/ESP-IDF, is there a documented guarantee that lwIP netif names use "st" for WiFi STA and "en" for Ethernet across supported versions? If not, what stable API should be used to identify the default WiFi/Ethernet netif?

💡 Result:

No—there is no documented, stable guarantee in ESP-IDF/Arduino-ESP32 that the underlying lwIP netif name will always use exactly “st” for WiFi STA and “en” for Ethernet across supported versions. In ESP-IDF, the recommended stable abstraction is ESP-NETIF: it creates and manages network interfaces and exposes handles for “default” WiFi (station/AP) and Ethernet interfaces. The ESP-NETIF API explicitly provides helpers for default WiFi STA/Ethernet initialization and returns an esp_netif_t handle, rather than requiring you to parse lwIP netif->name. For example, ESP-NETIF default Wi-Fi initialization is provided by functions that return an esp_netif handle (e.g., esp_netif_create_default_wifi_sta) and similarly Ethernet examples exist; the programming guide describes these as the convenient/default initialization paths. [1][2] If you still need to identify which underlying lwIP netif corresponds to an esp_netif_t, ESP-NETIF provides a stable API to query the “net interface name” used by the underlying TCP/IP stack implementation (lwIP): esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char *name). This is the API intended to read the implementation-specific name, not to rely on a fixed naming convention like “st”/“en”. [3] Stable approach to identify the default WiFi/Ethernet netif: 1) Use the ESP-NETIF default-interface creation APIs and keep the returned esp_netif_t handles. 2) If needed for compatibility/debugging, call esp_netif_get_netif_impl_name(handle, buf) to get the underlying lwIP name. Evidence: ESP-IDF’s ESP-NETIF documentation states that it “provides some convenient methods of creating the most common ones, such as Wi‑Fi and Ethernet” and that these APIs return an esp_netif handle configured with default settings. [1] Separately, the esp_netif API explicitly defines esp_netif_get_netif_impl_name as “Get net interface name from network stack implementation,” clarifying that the name comes from the underlying TCP/IP stack and is therefore implementation-/stack-dependent. [3] In contrast, the lwIP netif naming scheme (netif->name is only two characters plus index/num in classic lwIP) is an implementation detail of lwIP itself and is not presented by ESP-NETIF docs as a contractual guarantee to remain “st”/“en” forever. (So depending on netif->name for semantic identity is not a documented contract in ESP-IDF/ESP-NETIF.) [4]

Citations:


Fix fragile WiFi/Ethernet selection by removing hardcoded lwIP netif->name prefixes ("st"/"en")

wled00/network.cpp (lines 322-336) matches preferred interfaces by checking netif_iter->name against "st"/"en", but ESP-IDF/ESP-NETIF do not document a stable guarantee that lwIP will use those exact prefixes across versions/implementations—so primary selection can silently degrade to the wrong/fallback interface. Use ESP-NETIF’s default-interface creation APIs and keep the returned esp_netif_t handles (or map to the implementation-specific name via esp_netif_get_netif_impl_name()), instead of parsing netif->name.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wled00/network.cpp` around lines 322 - 336, The selection is fragile because
it matches netif_iter->name against hardcoded prefixes via targetName; instead,
track and use esp-netif handles or impl names provided by ESP-NETIF APIs rather
than parsing lwIP netif->name. Replace the prefix check around netif_iter (and
any use of targetName) by either (a) keeping the esp_netif_t returned when
creating the WiFi/ethernet interfaces and comparing netif_iter to
esp_netif_get_netif_impl_handle(...) (i.e., use the stored esp_netif_t handle
for the preferred interface) or (b) call
esp_netif_get_netif_impl_name(esp_netif_handle) to get the canonical impl name
and compare that, and then call netif_set_default() under LOCK_TCPIP_CORE() for
the chosen esp_netif/netif; remove reliance on literal "st"/"en" checks
(symbols: targetName, netif_iter, netif_list, LOCK_TCPIP_CORE,
netif_set_default, esp_netif_get_netif_impl_name, esp_netif_t).

target = netif_iter;
break;
}
if (!fallback) fallback = netif_iter;
}

// AI: if preferred interface unavailable, fall back to any ready interface
// prevents outbound traffic being pinned to a dead default netif
if (!target && fallback) {
target = fallback;
DEBUG_PRINTLN(F("setPNI: Preferred interface unavailable, using fallback"));
}

if (target != nullptr) {
netif_set_default(target);
DEBUG_PRINTF_P(PSTR("setPNI: Primary netif set to %c%c%d (%d.%d.%d.%d)\n"),
target->name[0], target->name[1], target->num,
ip4_addr1(&target->ip_addr.u_addr.ip4),
ip4_addr2(&target->ip_addr.u_addr.ip4),
ip4_addr3(&target->ip_addr.u_addr.ip4),
ip4_addr4(&target->ip_addr.u_addr.ip4));
} else {
DEBUG_PRINTLN(F("setPNI: No ready interface found, will retry on next IP event"));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

UNLOCK_TCPIP_CORE();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
#endif
// AI: end

//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp
int getSignalQuality(int rssi)
Expand Down Expand Up @@ -383,6 +460,7 @@ bool isWiFiConfigured() {
#define ARDUINO_EVENT_WIFI_SCAN_DONE SYSTEM_EVENT_SCAN_DONE
#define ARDUINO_EVENT_ETH_START SYSTEM_EVENT_ETH_START
#define ARDUINO_EVENT_ETH_CONNECTED SYSTEM_EVENT_ETH_CONNECTED
#define ARDUINO_EVENT_ETH_GOT_IP SYSTEM_EVENT_ETH_GOT_IP // AI: added for DHCP ethernet IP assignment event
#define ARDUINO_EVENT_ETH_DISCONNECTED SYSTEM_EVENT_ETH_DISCONNECTED
#endif

Expand Down Expand Up @@ -431,6 +509,11 @@ void WiFiEvent(WiFiEvent_t event)
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
DEBUG_PRINT(F("WiFi-E: IP address: ")); DEBUG_PRINTLN(Network.localIP());
// AI: re-evaluate primary network interface when WiFi gets its IP
// handles both static IP and DHCP scenarios for WiFi interface
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
setPrimaryNetworkInterface();
#endif
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
// followed by IDLE and SCAN_DONE
Expand Down Expand Up @@ -481,17 +564,30 @@ void WiFiEvent(WiFiEvent_t event)
case ARDUINO_EVENT_ETH_CONNECTED:
{
DEBUG_PRINTLN(F("ETH-E: Connected"));
if (!apActive) {
WiFi.disconnect(true); // disable WiFi entirely
}
char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters
getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name
// AI: WiFi is intentionally kept active when ethernet connects.
// Previously WiFi was disabled here to prevent routing conflicts, but
// with dual-interface support, netif_set_default() handles routing
// preference between interfaces. Disabling WiFi here would defeat the
// purpose of the feature entirely.
char hostname[64] = {'\0'};
getWLEDhostname(hostname, sizeof(hostname), true);
ETH.setHostname(hostname);
// AI: attempt to set default gateway interface on ethernet connect
setPrimaryNetworkInterface();
showWelcomePage = false;
break;
}
case ARDUINO_EVENT_ETH_GOT_IP:
// AI: ethernet DHCP IP assigned — now safe to set default netif
// this event is the reliable trigger for DHCP ethernet configuration
DEBUG_PRINT(F("ETH-E: Got IP: ")); DEBUG_PRINTLN(ETH.localIP());
setPrimaryNetworkInterface();
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
DEBUG_PRINTLN(F("ETH-E: Disconnected"));
// AI: re-evaluate primary network interface on ethernet disconnect
// ensures fallback to WiFi if ethernet was the primary interface
setPrimaryNetworkInterface();
// This doesn't really affect ethernet per se,
// as it's only configured once. Rather, it
// may be necessary to reconnect the WiFi when
Expand Down
50 changes: 50 additions & 0 deletions wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,60 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
}
#endif

// AI: below section was generated by an AI
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
ethernetType = request->arg(F("ETH")).toInt();
// AI: read ethernet static IP configuration from form POST.
// Each IP address is submitted as four separate octet fields (0-255),
// reassembled here into IPAddress objects matching the same pattern
// used for WiFi static IP fields (IP{n}0-3, GW{n}0-3, SN{n}0-3).
if (request->hasArg(F("EIP0"))) {
for (int i = 0; i < 4; i++) {
char eip[6], egw[6], esn[6];
snprintf_P(eip, sizeof(eip), PSTR("EIP%d"), i);
snprintf_P(egw, sizeof(egw), PSTR("EGW%d"), i);
snprintf_P(esn, sizeof(esn), PSTR("ESN%d"), i);
ethStaticIP[i] = request->arg(eip).toInt();
ethStaticGW[i] = request->arg(egw).toInt();
ethStaticSN[i] = request->arg(esn).toInt();
}
}
// AI: read primary network interface selection.
// PNI field value 0 = WiFi is primary interface, 1 = Ethernet is primary interface.
// Radio buttons only submit when selected so use hasArg with value check.
bool prevPrimaryInterface = ethPrimaryInterface;
ethPrimaryInterface = (request->arg(F("EPI")).toInt() == 1);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
bool ethPNIChanged = (ethPrimaryInterface != prevPrimaryInterface);
// AI: apply ethernet IP config changes immediately without reboot,
// bringing ethernet IP configuration to parity with WiFi live-update
// behaviour. Only calls ETH.config() if values actually changed,
// avoiding unnecessary network disruption on save.
// initEthernet() still called for first-time hardware init only.
if (ethernetType != WLED_ETH_NONE) {
IPAddress currentIP = ETH.localIP();
IPAddress currentGW = ETH.gatewayIP();
IPAddress currentSN = ETH.subnetMask();
bool ethIPChanged = (
(uint32_t)ethStaticIP != (uint32_t)currentIP ||
(uint32_t)ethStaticGW != (uint32_t)currentGW ||
(uint32_t)ethStaticSN != (uint32_t)currentSN
);
if (ethIPChanged) {
if ((uint32_t)ethStaticIP != 0) {
ETH.config(ethStaticIP, ethStaticGW, ethStaticSN, dnsAddress);
DEBUG_PRINTLN(F("ETH: IP config updated from settings"));
} else {
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
DEBUG_PRINTLN(F("ETH: Switched to DHCP from settings"));
}
}
if (ethIPChanged || ethPNIChanged) {
setPrimaryNetworkInterface();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
initEthernet();
#endif
// AI: end
}

//LED SETTINGS
Expand Down
Loading
Loading