diff --git a/src/NetworkModule.cpp b/src/NetworkModule.cpp index 700c211..647cc1e 100644 --- a/src/NetworkModule.cpp +++ b/src/NetworkModule.cpp @@ -169,6 +169,9 @@ void NetworkModule::loadSettings() length = 0; // will update by write knx.bau().propertyValueWrite(OT_IP_PARAMETER, 0, PID_FRIENDLY_NAME, elements, 1, friendlyNameWrite, 0); } + // propertyValueRead() allocated friendlyNameRead via new[] -> free it. + if (friendlyNameRead != nullptr) + delete[] friendlyNameRead; } if (_useStaticIP) @@ -236,8 +239,22 @@ void NetworkModule::esp32NetworkEvent(CALLBACK_EVENT event) break; case ARDUINO_EVENT_ETH_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP: + { + IPAddress ip = localIP(); logDebugP("Event: Got IP"); - controlKnxIp(true); + // Rebind multicast only on real IP change (avoid heap churn on lease renew). + if (ip != _boundIp) + { + controlKnxIp(false); + controlKnxIp(true); + _boundIp = ip; + } + break; + } + case ARDUINO_EVENT_ETH_LOST_IP: + case ARDUINO_EVENT_WIFI_STA_LOST_IP: + logDebugP("Event: Lost IP"); + controlKnxIp(false); break; case ARDUINO_EVENT_ETH_DISCONNECTED: case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: @@ -427,6 +444,11 @@ void NetworkModule::checkLinkStatus() // Get current network state bool establishedState = established(); + + // Keep KNX-IP datalink in lockstep with link/IP (idempotent). Recovers the + // case where GOT_IP doesn't re-fire after a link flap -> datalink stuck off. + controlKnxIp(establishedState); + bool newLinkState; if (establishedState) newLinkState = true; diff --git a/src/NetworkModule.h b/src/NetworkModule.h index ff513c8..dac0811 100644 --- a/src/NetworkModule.h +++ b/src/NetworkModule.h @@ -119,6 +119,7 @@ class NetworkModule : public OpenKNX::Module IPAddress _staticSubnetMask; IPAddress _staticGatewayIP; IPAddress _staticNameServerIP; + IPAddress _boundIp; // last IP the KNX multicast socket was bound to (rebind only on change) #ifdef ARDUINO_ARCH_ESP32 bool espConnected = false;