diff --git a/MQTT_IMPLEMENTATION.md b/MQTT_IMPLEMENTATION.md index 69fd7b58..f5a5f01e 100644 --- a/MQTT_IMPLEMENTATION.md +++ b/MQTT_IMPLEMENTATION.md @@ -864,6 +864,8 @@ the radio actually performs in that case. - Ethernet-preferred builds wait the full configured boot probe window for an Ethernet IP; delayed or unavailable PHY carrier reporting does not shorten the DHCP deadline. The boot selection log includes the measured probe duration. +- CH390 startup initializes Arduino's shared network event runtime without associating WiFi; + this keeps the framework's DNS and TLS hostname paths safe when Ethernet wins directly. - Ethernet/WiFi transitions are logged. A lost or changed route stops every started MQTT client, including one whose disconnect callback arrived first; once a usable route returns, route-caused backoff is cleared and one immediate reconnect is allowed diff --git a/src/helpers/NetworkInterface.cpp b/src/helpers/NetworkInterface.cpp index c22399a1..c8953aac 100644 --- a/src/helpers/NetworkInterface.cpp +++ b/src/helpers/NetworkInterface.cpp @@ -13,6 +13,12 @@ #if defined(NETWORK_PREFER_ETHERNET) #include "ethernet/ch390/CH390Config.h" + +// Arduino-ESP32's built-in ETH implementation calls this before bringing up +// Ethernet. It creates the shared Arduino network event group/task used by +// WiFiGenericClass::hostByName(), even when no Wi-Fi interface is started. +// ESP32-CH390 initializes esp_netif directly and omits this Arduino layer. +extern void tcpipInit(); #endif namespace { @@ -236,6 +242,10 @@ class EthernetNetworkInterface final : public NetworkInterfaceBase { bool begin(const char*, const char*) override { if (_started) return true; + // DNS and WiFiClientSecure are transport-neutral sockets in this Arduino + // core, but their hostname path still uses WiFiGeneric's event group. + // Initialize that shared runtime without enabling or associating Wi-Fi. + tcpipInit(); if (!_event_registered) { WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t) { switch (event) {