From 5b611db06e087cc3deaa2da06118aee0692b0dc5 Mon Sep 17 00:00:00 2001 From: gururaajar Date: Fri, 26 Jun 2026 13:35:50 -0400 Subject: [PATCH 1/7] onroutechange event implementation --- interface/INetworkManager.h | 1 + plugin/NetworkManager.h | 6 +++++ plugin/NetworkManagerImplementation.cpp | 27 ++++++++++++++++++++++ plugin/NetworkManagerImplementation.h | 2 ++ plugin/NetworkManagerJsonRpc.cpp | 13 +++++++++++ plugin/gnome/NetworkManagerGnomeEvents.cpp | 26 +++++++++++++++++++++ 6 files changed, 75 insertions(+) diff --git a/interface/INetworkManager.h b/interface/INetworkManager.h index ce8cb509..6d8f399c 100644 --- a/interface/INetworkManager.h +++ b/interface/INetworkManager.h @@ -282,6 +282,7 @@ namespace WPEFramework virtual void onInterfaceStateChange(const InterfaceState state /* @in */, const string interface /* @in */){}; virtual void onActiveInterfaceChange(const string prevActiveInterface /* @in */, const string currentActiveInterface /* @in */){}; virtual void onIPAddressChange(const string interface /* @in */, const string ipversion /* @in */, const string ipaddress /* @in */, const IPStatus status /* @in */){}; + virtual void onRouteChange(const string interface /* @in */, const string ipversion /* @in */, const string ipaddress /* @in */, const string gateway /* @in */, const string primarydns /* @in */){}; virtual void onInternetStatusChange(const InternetStatus prevState /* @in */, const InternetStatus currState /* @in */, const string interface /* @in */){}; // WiFi Notifications that other processes can subscribe to diff --git a/plugin/NetworkManager.h b/plugin/NetworkManager.h index 6a101bdf..d6317f28 100644 --- a/plugin/NetworkManager.h +++ b/plugin/NetworkManager.h @@ -79,6 +79,11 @@ namespace WPEFramework _parent.onIPAddressChange(interface, ipversion, ipaddress, status); } + void onRouteChange(const string interface, const string ipversion, const string ipaddress, const string gateway, const string primarydns) override + { + _parent.onRouteChange(interface, ipversion, ipaddress, gateway, primarydns); + } + void onInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface) override { _parent.onInternetStatusChange(prevState, currState, interface); @@ -260,6 +265,7 @@ namespace WPEFramework void onInterfaceStateChange(const Exchange::INetworkManager::InterfaceState state, const string interface); void onActiveInterfaceChange(const string prevActiveInterface, const string currentActiveinterface); void onIPAddressChange(const string interface, const string ipversion, const string ipaddress, const Exchange::INetworkManager::IPStatus status); + void onRouteChange(const string interface, const string ipversion, const string ipaddress, const string gateway, const string primarydns); void onInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface); void onAvailableSSIDs(const string jsonOfScanResults); void onWiFiStateChange(const Exchange::INetworkManager::WiFiState state); diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index b10b375b..f501b0cf 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -808,6 +808,33 @@ namespace WPEFramework _notificationLock.Unlock(); } + void NetworkManagerImplementation::ReportRouteChange(const string& interface, const string& ipversion) + { + string iface = interface; + Exchange::INetworkManager::IPAddress settings{}; + if (GetIPSettings(iface, ipversion, settings) != Core::ERROR_NONE) { + return; + } + ReportRouteChange(interface, ipversion, settings); + } + + void NetworkManagerImplementation::ReportRouteChange(const string& interface, const string& ipversion, const Exchange::INetworkManager::IPAddress& settings) + { + if (settings.ipaddress.empty() || settings.gateway.empty() || settings.primarydns.empty()) { + return; + } + + _notificationLock.Lock(); + NMLOG_INFO("Posting onRouteChange %s %s ip=%s gw=%s dns=%s", + interface.c_str(), ipversion.c_str(), settings.ipaddress.c_str(), + settings.gateway.c_str(), settings.primarydns.c_str()); + for (const auto callback : _notificationCallbacks) { + callback->onRouteChange(interface, settings.ipversion, settings.ipaddress, + settings.gateway, settings.primarydns); + } + _notificationLock.Unlock(); + } + void NetworkManagerImplementation::ReportInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface) { _notificationLock.Lock(); diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 65baa0b1..6726c631 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -318,6 +318,8 @@ namespace WPEFramework void ReportInterfaceStateChange(const Exchange::INetworkManager::InterfaceState state, const string interface); void ReportActiveInterfaceChange(const string prevActiveInterface, const string currentActiveinterface); void ReportIPAddressChange(const string interface, const string ipversion, const string ipaddress, const Exchange::INetworkManager::IPStatus status); + void ReportRouteChange(const string& interface, const string& ipversion); + void ReportRouteChange(const string& interface, const string& ipversion, const Exchange::INetworkManager::IPAddress& settings); void ReportInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface); void ReportAvailableSSIDs(const JsonArray &arrayofWiFiScanResults); void ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state); diff --git a/plugin/NetworkManagerJsonRpc.cpp b/plugin/NetworkManagerJsonRpc.cpp index d49e6c5d..fb92f425 100644 --- a/plugin/NetworkManagerJsonRpc.cpp +++ b/plugin/NetworkManagerJsonRpc.cpp @@ -1072,6 +1072,19 @@ namespace WPEFramework Notify(_T("onIPAddressChange"), parameters); } + void NetworkManager::onRouteChange(const string interface, const string ipversion, const string ipaddress, const string gateway, const string primarydns) + { + JsonObject parameters; + parameters["interface"] = interface; + parameters["ipversion"] = ipversion; + parameters["ipaddress"] = ipaddress; + parameters["gateway"] = gateway; + parameters["primarydns"] = primarydns; + + LOG_INPARAM(); + Notify(_T("onRouteChange"), parameters); + } + void NetworkManager::onInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface) { JsonObject parameters; diff --git a/plugin/gnome/NetworkManagerGnomeEvents.cpp b/plugin/gnome/NetworkManagerGnomeEvents.cpp index 7a87cc20..3bd4830a 100644 --- a/plugin/gnome/NetworkManagerGnomeEvents.cpp +++ b/plugin/gnome/NetworkManagerGnomeEvents.cpp @@ -197,6 +197,23 @@ namespace WPEFramework _instance->ReportIPAddressChange(ifname, family, key, Exchange::INetworkManager::IP_LOST); } } + + /* Coalesced "route ready" event: emit once address + gateway + primary DNS + are all populated for this family. The notify::addresses / + notify::gateway / notify::nameservers subscriptions on NMIPConfig all + funnel here, so a single emission per snapshot covers all three. + Each family emits independently — dual-stack consumers will see one + event per family. */ + if (newCache.valid + && !newCache.globalAddresses.empty() + && !newCache.gateway.empty() + && !newCache.primarydns.empty()) { + /* Values are already in hand from the snapshot we just built, so emit + them directly instead of having ReportRouteChange re-query the cache. */ + Exchange::INetworkManager::IPAddress settings = newCache.toIPAddress(); + settings.ipversion = family; + _instance->ReportRouteChange(ifname, family, settings); + } } static void ip4ChangedCb(NMIPConfig *ipConfig, GParamSpec *pspec, gpointer userData) @@ -842,6 +859,15 @@ namespace WPEFramework _instance->ReportActiveInterfaceChange(oldIface, newIface); NMLOG_INFO("old interface - %s new interface - %s", oldIface.c_str(), newIface.c_str()); oldIface = newIface; + + /* Default-route owner changed (e.g. eth0↔wlan0 failover). The new primary + already has its IP/gateway/DNS in the cache from prior refreshIpFamilyCache, + so emit a coalesced route-ready event for both families — ReportRouteChange + is a no-op for whichever family isn't fully populated. */ + if (_instance != nullptr && !newIface.empty() && newIface != "Unknown") { + _instance->ReportRouteChange(newIface, "IPv4"); + _instance->ReportRouteChange(newIface, "IPv6"); + } } } From 41427c975b963779b05ae7880059ca3e2dca7d90 Mon Sep 17 00:00:00 2001 From: Gururaaja E S R Date: Thu, 16 Jul 2026 13:47:51 -0400 Subject: [PATCH 2/7] Added macro to conditional compilation --- CMakeLists.txt | 2 + plugin/CMakeLists.txt | 7 +++ plugin/NetworkManagerImplementation.cpp | 41 ++++++++++++--- plugin/NetworkManagerImplementation.h | 4 ++ plugin/NetworkManagerJsonRpc.cpp | 67 ++++++++++++++++++++++++- 5 files changed, 112 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d4cc1db..2f7fb3ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,8 @@ option(ENABLE_LEGACY_PLUGINS "Enable Legacy Plugins" ON) option(USE_RDK_LOGGER "Enable RDK Logger for logging" OFF ) option(ENABLE_UNIT_TESTING "Enable unit tests" OFF) option(USE_TELEMETRY "Enable Telemetry T2 support" OFF) +option(USE_CONNECTIVITY_CHECK_MGR + "Delegate internet-connectivity queries to the ConnectivityCheckMgr plugin" OFF) option(ENABLE_ETHERNET_CONNECTION_HANDLING "Enable pre-sleep Ethernet deactivation" OFF) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 6090b8f1..3aab7e21 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -84,6 +84,13 @@ add_library(${MODULE_IMPL_NAME} SHARED NetworkManagerPowerClient.cpp Module.cpp) +# When enabled, JSON-RPC methods in the shell delegate connectivity queries +# to ConnectivityCheckMgr via QueryInterfaceByCallsign. +if(USE_CONNECTIVITY_CHECK_MGR) + target_compile_definitions(${MODULE_NAME} PRIVATE USE_CONNECTIVITY_CHECK_MGR) + target_compile_definitions(${MODULE_IMPL_NAME} PRIVATE USE_CONNECTIVITY_CHECK_MGR) +endif() + if(ENABLE_GNOME_NETWORKMANAGER) if(ENABLE_GNOME_GDBUS) message("networkmanager building with gdbus") diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index f501b0cf..09869999 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -77,7 +77,9 @@ namespace WPEFramework { NMLOG_INFO("NetworkManager Out-Of-Process Shutdown/Cleanup"); m_powerClient.reset(); +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.stopConnectivityMonitor(); +#endif _instance = nullptr; platform_deinit(); if(m_registrationThread.joinable()) @@ -187,19 +189,22 @@ namespace WPEFramework connectEndpts.push_back(config.connectivityConf.endpoint_5.Value().c_str()); } - /* check whether the endpoint is already loaded from Cache; if Yes, do not use the one from configuration */ - if (connectivityMonitor.getConnectivityMonitorEndpoints().size() < 1) - { - NMLOG_INFO("Use the connectivity endpoint from config"); - connectivityMonitor.setConnectivityMonitorEndpoints(connectEndpts); - } - else if (connectEndpts.size() < 1) + if (connectEndpts.size() < 1) { std::vector backup; NMLOG_INFO("Connectivity endpoints are empty in config; use the default"); backup.push_back("http://clients3.google.com/generate_204"); +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.setConnectivityMonitorEndpoints(backup); +#endif + } +#ifndef USE_CONNECTIVITY_CHECK_MGR + else if (connectivityMonitor.getConnectivityMonitorEndpoints().size() < 1) + { + NMLOG_INFO("Use the connectivity endpoint from config"); + connectivityMonitor.setConnectivityMonitorEndpoints(connectEndpts); } +#endif /* As all the configuration is set, lets instantiate platform */ NetworkManagerImplementation::platform_init(); @@ -256,7 +261,10 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::GetConnectivityTestEndpoints(IStringIterator*& endpoints/* @out */) const { LOG_ENTRY_FUNCTION(); - std::vector tmpEndpoints = connectivityMonitor.getConnectivityMonitorEndpoints(); + std::vector tmpEndpoints; +#ifndef USE_CONNECTIVITY_CHECK_MGR + tmpEndpoints = connectivityMonitor.getConnectivityMonitorEndpoints(); +#endif endpoints = (Core::Service::Create(tmpEndpoints)); if(endpoints == nullptr) { return Core::ERROR_GENERAL; @@ -282,7 +290,9 @@ namespace WPEFramework tmpEndpoints.push_back(endpoint); } } +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.setConnectivityMonitorEndpoints(tmpEndpoints); +#endif } return Core::ERROR_NONE; } @@ -315,7 +325,12 @@ namespace WPEFramework return Core::ERROR_BAD_REQUEST; } +#ifdef USE_CONNECTIVITY_CHECK_MGR + (void)ipVersionNotSpecified; + result = INTERNET_UNKNOWN; +#else result = connectivityMonitor.getInternetState(interface, curlIPversion, ipVersionNotSpecified); +#endif if (Exchange::INetworkManager::IP_ADDRESS_V6 == curlIPversion) ipversion = "IPv6"; else @@ -331,7 +346,11 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::GetCaptivePortalURI(string &uri /* @out */) const { LOG_ENTRY_FUNCTION(); +#ifdef USE_CONNECTIVITY_CHECK_MGR + uri.clear(); +#else uri = connectivityMonitor.getCaptivePortalURI(); +#endif return Core::ERROR_NONE; } @@ -681,7 +700,9 @@ namespace WPEFramework m_ethConnected.store(false); setDefaultInterface("wlan0"); // If WiFi is connected, make it the default interface // As default interface is changed to wlan0, switch connectivity monitor to initial check +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.switchToInitialCheck(); +#endif } else if(interface == "wlan0") { @@ -698,7 +719,9 @@ namespace WPEFramework { // When WiFi is disconnected while Ethernet is connected, we don't need to trigger connectivity monitor. // For WiFi-only state and WiFi disconnected, we should trigger connectivity monitor. +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.switchToInitialCheck(); +#endif } } } @@ -792,7 +815,9 @@ namespace WPEFramework if(isDefaultIface) { // As default interface is connected, switch connectivity monitor to initial check any way +#ifndef USE_CONNECTIVITY_CHECK_MGR connectivityMonitor.switchToInitialCheck(); +#endif } else NMLOG_DEBUG("No need to trigger connectivity monitor interface is %s", interface.c_str()); diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 6726c631..5e23ae75 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -35,7 +35,9 @@ using namespace std; #include "INetworkManager.h" #include "NetworkManagerLogger.h" +#ifndef USE_CONNECTIVITY_CHECK_MGR #include "NetworkManagerConnectivity.h" +#endif #include "NetworkManagerStunClient.h" #include "NetworkManagerPowerClient.h" @@ -392,7 +394,9 @@ namespace WPEFramework std::atomic m_wlanDisconnectedForSleep; std::string m_lastConnectedSSID; GMainContext *m_nmContext{nullptr}; /* isolated context for per-call NMClient creation */ +#ifndef USE_CONNECTIVITY_CHECK_MGR mutable ConnectivityMonitor connectivityMonitor; +#endif string getDefaultInterface() const { diff --git a/plugin/NetworkManagerJsonRpc.cpp b/plugin/NetworkManagerJsonRpc.cpp index fb92f425..e0ff1cca 100644 --- a/plugin/NetworkManagerJsonRpc.cpp +++ b/plugin/NetworkManagerJsonRpc.cpp @@ -20,6 +20,9 @@ #include "NetworkManager.h" #include "INetworkManager.h" #include "NetworkManagerJsonEnum.h" +#ifdef USE_CONNECTIVITY_CHECK_MGR +#include +#endif #define LOG_INPARAM() { string json; parameters.ToString(json); NMLOG_INFO("params=%s", json.c_str() ); } #define LOG_OUTPARAM() { string json; response.ToString(json); NMLOG_INFO("response=%s", json.c_str() ); } @@ -37,6 +40,27 @@ using namespace NetworkManagerLogger; +#ifdef USE_CONNECTIVITY_CHECK_MGR +namespace { +Exchange::INetworkManager::InternetStatus MapConnectivityStatus(const Exchange::IConnectivityCheck::InternetStatus status) +{ + switch (status) { + case Exchange::IConnectivityCheck::NO_INTERNET: + return Exchange::INetworkManager::INTERNET_NOT_AVAILABLE; + case Exchange::IConnectivityCheck::LIMITED_INTERNET: + return Exchange::INetworkManager::INTERNET_LIMITED; + case Exchange::IConnectivityCheck::CAPTIVE_PORTAL: + return Exchange::INetworkManager::INTERNET_CAPTIVE_PORTAL; + case Exchange::IConnectivityCheck::FULLY_CONNECTED: + return Exchange::INetworkManager::INTERNET_FULLY_CONNECTED; + case Exchange::IConnectivityCheck::UNKNOWN: + default: + return Exchange::INetworkManager::INTERNET_UNKNOWN; + } +} +} +#endif + namespace WPEFramework { namespace Plugin @@ -448,7 +472,7 @@ namespace WPEFramework { LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; - Exchange::INetworkManager::InternetStatus result; + Exchange::INetworkManager::InternetStatus result = Exchange::INetworkManager::INTERNET_UNKNOWN; string ipversion{}; string interface{}; @@ -457,10 +481,35 @@ namespace WPEFramework if (parameters.HasLabel("interface")) interface = parameters["interface"].String(); +#ifdef USE_CONNECTIVITY_CHECK_MGR + if (_service != nullptr) { + Exchange::IConnectivityCheck* connectivity = + _service->QueryInterfaceByCallsign("org.rdk.ConnectivityCheckMgr"); + if (connectivity != nullptr) { + Exchange::IConnectivityCheck::StatusInfo info{}; + rc = connectivity->GetInternetStatus(info); + if (rc == Core::ERROR_NONE) { + result = MapConnectivityStatus(info.status); + if (!info.ipversion.empty()) { + ipversion = info.ipversion; + } + if (!info.interface.empty()) { + interface = info.interface; + } + } + connectivity->Release(); + } else { + rc = Core::ERROR_UNAVAILABLE; + } + } else { + rc = Core::ERROR_UNAVAILABLE; + } +#else if (_networkManager) rc = _networkManager->IsConnectedToInternet(ipversion, interface, result); else rc = Core::ERROR_UNAVAILABLE; +#endif if (Core::ERROR_NONE == rc) { @@ -479,10 +528,26 @@ namespace WPEFramework LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; string uri; + +#ifdef USE_CONNECTIVITY_CHECK_MGR + if (_service != nullptr) { + Exchange::IConnectivityCheck* connectivity = + _service->QueryInterfaceByCallsign("org.rdk.ConnectivityCheckMgr"); + if (connectivity != nullptr) { + rc = connectivity->GetCaptivePortalURI(uri); + connectivity->Release(); + } else { + rc = Core::ERROR_UNAVAILABLE; + } + } else { + rc = Core::ERROR_UNAVAILABLE; + } +#else if (_networkManager) rc = _networkManager->GetCaptivePortalURI(uri); else rc = Core::ERROR_UNAVAILABLE; +#endif if (Core::ERROR_NONE == rc) response["uri"] = uri; From fa3bf10d42e4dd7b60556d673788c890c4d4871f Mon Sep 17 00:00:00 2001 From: Gururaaja E S R Date: Thu, 16 Jul 2026 15:03:42 -0400 Subject: [PATCH 3/7] Modified the code to have separate client to get connectivity status form the connectivity plugin --- plugin/CMakeLists.txt | 12 +- plugin/NetworkManagerConnectivityClient.cpp | 123 ++++++++++++++++++++ plugin/NetworkManagerConnectivityClient.h | 84 +++++++++++++ plugin/NetworkManagerImplementation.cpp | 4 +- plugin/NetworkManagerImplementation.h | 8 +- plugin/NetworkManagerJsonRpc.cpp | 67 +---------- 6 files changed, 224 insertions(+), 74 deletions(-) create mode 100644 plugin/NetworkManagerConnectivityClient.cpp create mode 100644 plugin/NetworkManagerConnectivityClient.h diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 3aab7e21..8677beea 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -78,17 +78,21 @@ set_target_properties(${MODULE_NAME} PROPERTIES add_library(${MODULE_IMPL_NAME} SHARED NetworkManagerImplementation.cpp - NetworkManagerConnectivity.cpp NetworkManagerStunClient.cpp NetworkManagerLogger.cpp NetworkManagerPowerClient.cpp Module.cpp) -# When enabled, JSON-RPC methods in the shell delegate connectivity queries -# to ConnectivityCheckMgr via QueryInterfaceByCallsign. +# Connectivity source selection: when enabled, the out-of-process implementation +# delegates internet-connectivity queries to the ConnectivityCheckMgr plugin via +# a COM-RPC client. This covers both the JSON-RPC surface (shell -> impl) and +# direct COM-RPC callers of INetworkManager. Otherwise the built-in +# ConnectivityMonitor is used. STUN is unaffected either way. if(USE_CONNECTIVITY_CHECK_MGR) - target_compile_definitions(${MODULE_NAME} PRIVATE USE_CONNECTIVITY_CHECK_MGR) target_compile_definitions(${MODULE_IMPL_NAME} PRIVATE USE_CONNECTIVITY_CHECK_MGR) + target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivityClient.cpp) +else() + target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivity.cpp) endif() if(ENABLE_GNOME_NETWORKMANAGER) diff --git a/plugin/NetworkManagerConnectivityClient.cpp b/plugin/NetworkManagerConnectivityClient.cpp new file mode 100644 index 00000000..7725b55f --- /dev/null +++ b/plugin/NetworkManagerConnectivityClient.cpp @@ -0,0 +1,123 @@ +/** +* If not stated otherwise in this file or this component's LICENSE +* file the following copyright and licenses apply: +* +* Copyright 2026 RDK Management +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#include "NetworkManagerConnectivityClient.h" +#include "NetworkManagerLogger.h" +#include + +using namespace WPEFramework; +using namespace WPEFramework::Exchange; +using namespace WPEFramework::Plugin; + +// --------------------------------------------------------------------------- +// NetworkManagerConnectivityClient +// --------------------------------------------------------------------------- + +NetworkManagerConnectivityClient::NetworkManagerConnectivityClient() +{ + NMLOG_INFO("connecting to ConnectivityCheckMgr"); + if (auto r = Open(RPC::CommunicationTimeOut, Connector(), "org.rdk.ConnectivityCheckMgr"); r == Core::ERROR_NONE) { + // Connected; Operational() will be called by the framework when the proxy is ready. + } else { + NMLOG_ERROR("failed to open link to ConnectivityCheckMgr (error %u)", r); + } +} + +NetworkManagerConnectivityClient::~NetworkManagerConnectivityClient() +{ + NMLOG_INFO("shutting down"); + { + std::lock_guard lock(mLock); + if (mConnectivity != nullptr) { + mConnectivity->Release(); + mConnectivity = nullptr; + } + } + Close(Core::infinite); +} + +bool NetworkManagerConnectivityClient::IsValid() const +{ + LOG_ENTRY_FUNCTION(); + std::lock_guard lock(mLock); + return mConnectivity != nullptr; +} + +void NetworkManagerConnectivityClient::Operational(bool upAndRunning) +{ + NMLOG_DEBUG("Operational(%s)", upAndRunning ? "true" : "false"); + std::lock_guard lock(mLock); + if (upAndRunning) { + if (mConnectivity == nullptr) { + mConnectivity = Interface(); + } + } else { + if (mConnectivity != nullptr) { + mConnectivity->Release(); + mConnectivity = nullptr; + } + } +} + +NetworkManagerConnectivityClient::NmInternetStatus +NetworkManagerConnectivityClient::mapStatus(Exchange::IConnectivityCheck::InternetStatus status) +{ + switch (status) { + case Exchange::IConnectivityCheck::NO_INTERNET: return Exchange::INetworkManager::INTERNET_NOT_AVAILABLE; + case Exchange::IConnectivityCheck::LIMITED_INTERNET: return Exchange::INetworkManager::INTERNET_LIMITED; + case Exchange::IConnectivityCheck::CAPTIVE_PORTAL: return Exchange::INetworkManager::INTERNET_CAPTIVE_PORTAL; + case Exchange::IConnectivityCheck::FULLY_CONNECTED: return Exchange::INetworkManager::INTERNET_FULLY_CONNECTED; + case Exchange::IConnectivityCheck::UNKNOWN: + default: return Exchange::INetworkManager::INTERNET_UNKNOWN; + } +} + +NetworkManagerConnectivityClient::NmInternetStatus +NetworkManagerConnectivityClient::getInternetState() +{ + LOG_ENTRY_FUNCTION(); + std::lock_guard lock(mLock); + if (mConnectivity == nullptr) { + NMLOG_WARNING("ConnectivityCheckMgr not available; returning INTERNET_UNKNOWN"); + return Exchange::INetworkManager::INTERNET_UNKNOWN; + } + + Exchange::IConnectivityCheck::StatusInfo info{}; + if (auto r = mConnectivity->GetInternetStatus(info); r != Core::ERROR_NONE) { + NMLOG_ERROR("ConnectivityCheckMgr GetInternetStatus failed (%u)", r); + return Exchange::INetworkManager::INTERNET_UNKNOWN; + } + return mapStatus(info.status); +} + +std::string NetworkManagerConnectivityClient::getCaptivePortalURI() +{ + LOG_ENTRY_FUNCTION(); + std::lock_guard lock(mLock); + std::string uri; + if (mConnectivity == nullptr) { + NMLOG_WARNING("ConnectivityCheckMgr not available; returning empty captive-portal URI"); + return uri; + } + if (auto r = mConnectivity->GetCaptivePortalURI(uri); r != Core::ERROR_NONE) { + NMLOG_ERROR("ConnectivityCheckMgr GetCaptivePortalURI failed (%u)", r); + uri.clear(); + } + return uri; +} diff --git a/plugin/NetworkManagerConnectivityClient.h b/plugin/NetworkManagerConnectivityClient.h new file mode 100644 index 00000000..59e859bb --- /dev/null +++ b/plugin/NetworkManagerConnectivityClient.h @@ -0,0 +1,84 @@ +/** +* If not stated otherwise in this file or this component's LICENSE +* file the following copyright and licenses apply: +* +* Copyright 2026 RDK Management +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#pragma once + +#include "Module.h" +#include "INetworkManager.h" +#include +#include +#include + +namespace WPEFramework { +namespace Plugin { + +/** + * COM-RPC client that delegates internet-connectivity queries to the + * ConnectivityCheckMgr plugin (org.rdk.ConnectivityCheckMgr). + * + * Because the delegation lives in the out-of-process implementation, both the + * JSON-RPC surface (shell -> implementation) and direct COM-RPC callers of + * INetworkManager::IsConnectedToInternet / GetCaptivePortalURI are served + * consistently. + * + * Mirrors NetworkManagerPowerClient: + * - Inherits SmartInterfaceType for automatic + * connect / reconnect and Operational() lifecycle callbacks. + * + * Lifecycle: + * Construction -> Open() connects to ConnectivityCheckMgr (async). + * Operational(true) -> acquires the proxy; IsValid() returns true. + * Operational(false) -> releases the proxy. + * Destruction -> Close(). + * + * All queries fall back to INTERNET_UNKNOWN / empty when the plugin is not + * available, so callers never crash on a boot-order race or NM/CCM restart. + */ +class NetworkManagerConnectivityClient : protected RPC::SmartInterfaceType { +public: + using NmInternetStatus = Exchange::INetworkManager::InternetStatus; + + NetworkManagerConnectivityClient(); + ~NetworkManagerConnectivityClient() override; + + NetworkManagerConnectivityClient(const NetworkManagerConnectivityClient&) = delete; + NetworkManagerConnectivityClient& operator=(const NetworkManagerConnectivityClient&) = delete; + + /** Returns true when the ConnectivityCheckMgr COMRPC proxy is available. */ + bool IsValid() const; + + /** Delegated internet status, mapped to NetworkManager's InternetStatus. */ + NmInternetStatus getInternetState(); + + /** Delegated captive-portal URI (empty when unavailable / not captive). */ + std::string getCaptivePortalURI(); + +private: + // SmartInterfaceType lifecycle callback. + void Operational(bool upAndRunning) override; + + // 1:1 mapping ConnectivityCheckMgr InternetStatus -> NetworkManager InternetStatus. + static NmInternetStatus mapStatus(Exchange::IConnectivityCheck::InternetStatus status); + + mutable std::mutex mLock; + Exchange::IConnectivityCheck* mConnectivity{nullptr}; +}; + +} // namespace Plugin +} // namespace WPEFramework diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index 09869999..027ea20e 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -327,7 +327,7 @@ namespace WPEFramework #ifdef USE_CONNECTIVITY_CHECK_MGR (void)ipVersionNotSpecified; - result = INTERNET_UNKNOWN; + result = connectivityClient.getInternetState(); #else result = connectivityMonitor.getInternetState(interface, curlIPversion, ipVersionNotSpecified); #endif @@ -347,7 +347,7 @@ namespace WPEFramework { LOG_ENTRY_FUNCTION(); #ifdef USE_CONNECTIVITY_CHECK_MGR - uri.clear(); + uri = connectivityClient.getCaptivePortalURI(); #else uri = connectivityMonitor.getCaptivePortalURI(); #endif diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 5e23ae75..70f8a85b 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -35,7 +35,9 @@ using namespace std; #include "INetworkManager.h" #include "NetworkManagerLogger.h" -#ifndef USE_CONNECTIVITY_CHECK_MGR +#ifdef USE_CONNECTIVITY_CHECK_MGR +#include "NetworkManagerConnectivityClient.h" +#else #include "NetworkManagerConnectivity.h" #endif #include "NetworkManagerStunClient.h" @@ -394,7 +396,9 @@ namespace WPEFramework std::atomic m_wlanDisconnectedForSleep; std::string m_lastConnectedSSID; GMainContext *m_nmContext{nullptr}; /* isolated context for per-call NMClient creation */ -#ifndef USE_CONNECTIVITY_CHECK_MGR +#ifdef USE_CONNECTIVITY_CHECK_MGR + mutable NetworkManagerConnectivityClient connectivityClient; +#else mutable ConnectivityMonitor connectivityMonitor; #endif diff --git a/plugin/NetworkManagerJsonRpc.cpp b/plugin/NetworkManagerJsonRpc.cpp index e0ff1cca..fb92f425 100644 --- a/plugin/NetworkManagerJsonRpc.cpp +++ b/plugin/NetworkManagerJsonRpc.cpp @@ -20,9 +20,6 @@ #include "NetworkManager.h" #include "INetworkManager.h" #include "NetworkManagerJsonEnum.h" -#ifdef USE_CONNECTIVITY_CHECK_MGR -#include -#endif #define LOG_INPARAM() { string json; parameters.ToString(json); NMLOG_INFO("params=%s", json.c_str() ); } #define LOG_OUTPARAM() { string json; response.ToString(json); NMLOG_INFO("response=%s", json.c_str() ); } @@ -40,27 +37,6 @@ using namespace NetworkManagerLogger; -#ifdef USE_CONNECTIVITY_CHECK_MGR -namespace { -Exchange::INetworkManager::InternetStatus MapConnectivityStatus(const Exchange::IConnectivityCheck::InternetStatus status) -{ - switch (status) { - case Exchange::IConnectivityCheck::NO_INTERNET: - return Exchange::INetworkManager::INTERNET_NOT_AVAILABLE; - case Exchange::IConnectivityCheck::LIMITED_INTERNET: - return Exchange::INetworkManager::INTERNET_LIMITED; - case Exchange::IConnectivityCheck::CAPTIVE_PORTAL: - return Exchange::INetworkManager::INTERNET_CAPTIVE_PORTAL; - case Exchange::IConnectivityCheck::FULLY_CONNECTED: - return Exchange::INetworkManager::INTERNET_FULLY_CONNECTED; - case Exchange::IConnectivityCheck::UNKNOWN: - default: - return Exchange::INetworkManager::INTERNET_UNKNOWN; - } -} -} -#endif - namespace WPEFramework { namespace Plugin @@ -472,7 +448,7 @@ namespace WPEFramework { LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; - Exchange::INetworkManager::InternetStatus result = Exchange::INetworkManager::INTERNET_UNKNOWN; + Exchange::INetworkManager::InternetStatus result; string ipversion{}; string interface{}; @@ -481,35 +457,10 @@ namespace WPEFramework if (parameters.HasLabel("interface")) interface = parameters["interface"].String(); -#ifdef USE_CONNECTIVITY_CHECK_MGR - if (_service != nullptr) { - Exchange::IConnectivityCheck* connectivity = - _service->QueryInterfaceByCallsign("org.rdk.ConnectivityCheckMgr"); - if (connectivity != nullptr) { - Exchange::IConnectivityCheck::StatusInfo info{}; - rc = connectivity->GetInternetStatus(info); - if (rc == Core::ERROR_NONE) { - result = MapConnectivityStatus(info.status); - if (!info.ipversion.empty()) { - ipversion = info.ipversion; - } - if (!info.interface.empty()) { - interface = info.interface; - } - } - connectivity->Release(); - } else { - rc = Core::ERROR_UNAVAILABLE; - } - } else { - rc = Core::ERROR_UNAVAILABLE; - } -#else if (_networkManager) rc = _networkManager->IsConnectedToInternet(ipversion, interface, result); else rc = Core::ERROR_UNAVAILABLE; -#endif if (Core::ERROR_NONE == rc) { @@ -528,26 +479,10 @@ namespace WPEFramework LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; string uri; - -#ifdef USE_CONNECTIVITY_CHECK_MGR - if (_service != nullptr) { - Exchange::IConnectivityCheck* connectivity = - _service->QueryInterfaceByCallsign("org.rdk.ConnectivityCheckMgr"); - if (connectivity != nullptr) { - rc = connectivity->GetCaptivePortalURI(uri); - connectivity->Release(); - } else { - rc = Core::ERROR_UNAVAILABLE; - } - } else { - rc = Core::ERROR_UNAVAILABLE; - } -#else if (_networkManager) rc = _networkManager->GetCaptivePortalURI(uri); else rc = Core::ERROR_UNAVAILABLE; -#endif if (Core::ERROR_NONE == rc) response["uri"] = uri; From 0aa3f05d10e4c60b87579bf3d4ca09d6d00e14b7 Mon Sep 17 00:00:00 2001 From: Gururaaja E S R Date: Fri, 24 Jul 2026 13:34:12 -0400 Subject: [PATCH 4/7] Added RFC for connectivity manager enabling in networkmanager --- CMakeLists.txt | 2 - plugin/CMakeLists.txt | 31 ++++-- plugin/NetworkManager.conf.in | 1 + plugin/NetworkManager.config | 1 + plugin/NetworkManagerImplementation.cpp | 126 +++++++++++++++------- plugin/NetworkManagerImplementation.h | 25 +++-- tests/l2Test/rdk/l2_test_rdkproxyImpl.cpp | 10 +- 7 files changed, 134 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f7fb3ed..6d4cc1db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,8 +55,6 @@ option(ENABLE_LEGACY_PLUGINS "Enable Legacy Plugins" ON) option(USE_RDK_LOGGER "Enable RDK Logger for logging" OFF ) option(ENABLE_UNIT_TESTING "Enable unit tests" OFF) option(USE_TELEMETRY "Enable Telemetry T2 support" OFF) -option(USE_CONNECTIVITY_CHECK_MGR - "Delegate internet-connectivity queries to the ConnectivityCheckMgr plugin" OFF) option(ENABLE_ETHERNET_CONNECTION_HANDLING "Enable pre-sleep Ethernet deactivation" OFF) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 8677beea..c2acd732 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -51,6 +51,7 @@ endif () set(PLUGIN_NETWORKMANAGER_LOGLEVEL "5" CACHE STRING "To configure default loglevel NetworkManager plugin") set(PLUGIN_NETWORKMANAGER_STARTUPORDER "25" CACHE STRING "To configure startup order of Unified NetworkManager plugin") +set(PLUGIN_NETWORKMANAGER_USE_CONNECTIVITYCHECKMGR "false" CACHE STRING "Config fallback to delegate connectivity to ConnectivityCheckMgr when the RFC flag is unset") set(PLUGIN_BUILD_REFERENCE ${PROJECT_VERSION} CACHE STRING "To Set the Hash for the plugin") add_definitions(-DPLUGIN_BUILD_REFERENCE=${PLUGIN_BUILD_REFERENCE}) @@ -83,16 +84,26 @@ add_library(${MODULE_IMPL_NAME} SHARED NetworkManagerPowerClient.cpp Module.cpp) -# Connectivity source selection: when enabled, the out-of-process implementation -# delegates internet-connectivity queries to the ConnectivityCheckMgr plugin via -# a COM-RPC client. This covers both the JSON-RPC surface (shell -> impl) and -# direct COM-RPC callers of INetworkManager. Otherwise the built-in -# ConnectivityMonitor is used. STUN is unaffected either way. -if(USE_CONNECTIVITY_CHECK_MGR) - target_compile_definitions(${MODULE_IMPL_NAME} PRIVATE USE_CONNECTIVITY_CHECK_MGR) - target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivityClient.cpp) -else() - target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivity.cpp) +# Connectivity backend: both the built-in ConnectivityMonitor and the +# ConnectivityCheckMgr delegation client are always compiled. Selection between +# them is made at runtime (see resolveConnectivityCheckMgrEnabled) from the RFC +# flag Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable +# with a config-line fallback. STUN is unaffected either way. +target_sources(${MODULE_IMPL_NAME} PRIVATE + NetworkManagerConnectivity.cpp + NetworkManagerConnectivityClient.cpp) + +# Optional RFC API support (for reading TR-181 RFC feature flags at runtime). +option(USE_RFCAPI "Enable RFC API for TR-181 feature flag access" OFF) +if(USE_RFCAPI) + find_library(RFCAPI_LIBRARY rfcapi REQUIRED) + find_path(RFCAPI_INCLUDE_DIR rfcapi.h) + target_compile_definitions(${MODULE_IMPL_NAME} PRIVATE USE_RFCAPI) + target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_LIBRARY}) + if(RFCAPI_INCLUDE_DIR) + target_include_directories(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_INCLUDE_DIR}) + endif() + message(STATUS "NetworkManager RFC API support: enabled") endif() if(ENABLE_GNOME_NETWORKMANAGER) diff --git a/plugin/NetworkManager.conf.in b/plugin/NetworkManager.conf.in index b4876296..d98fb720 100644 --- a/plugin/NetworkManager.conf.in +++ b/plugin/NetworkManager.conf.in @@ -24,4 +24,5 @@ configuration.add("root", process) configuration.add("connectivity", connectivity) configuration.add("stun", stun) configuration.add("loglevel", "@PLUGIN_NETWORKMANAGER_LOGLEVEL@") +configuration.add("useConnectivityCheckMgr", "@PLUGIN_NETWORKMANAGER_USE_CONNECTIVITYCHECKMGR@") diff --git a/plugin/NetworkManager.config b/plugin/NetworkManager.config index 59563509..04d57f60 100644 --- a/plugin/NetworkManager.config +++ b/plugin/NetworkManager.config @@ -23,5 +23,6 @@ map() kv(interval, 30) end() kv(loglevel, 3) + kv(useConnectivityCheckMgr, ${PLUGIN_NETWORKMANAGER_USE_CONNECTIVITYCHECKMGR}) end() ans(configuration) diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index 027ea20e..d8087887 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -24,6 +24,11 @@ #include #include "NetworkManagerImplementation.h" +#ifdef USE_RFCAPI +#include +#include "rfcapi.h" +#endif + #if USE_TELEMETRY #include "NetworkManagerJsonEnum.h" #include @@ -60,6 +65,11 @@ namespace WPEFramework m_ethDisconnectedForSleep.store(false); m_wlanDisconnectedForSleep.store(false); + /* Default connectivity backend is the built-in monitor. Configure() + * may switch to ConnectivityCheckMgr delegation based on the RFC flag + * (see resolveConnectivityCheckMgrEnabled). */ + connectivityMonitor.reset(new ConnectivityMonitor()); + /* Set NetworkManager Out-Process name to be NWMgrPlugin */ Core::ProcessInfo().Name("NWMgrPlugin"); @@ -77,9 +87,10 @@ namespace WPEFramework { NMLOG_INFO("NetworkManager Out-Of-Process Shutdown/Cleanup"); m_powerClient.reset(); -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.stopConnectivityMonitor(); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + { + connectivityMonitor->stopConnectivityMonitor(); + } _instance = nullptr; platform_deinit(); if(m_registrationThread.joinable()) @@ -156,6 +167,26 @@ namespace WPEFramework NetworkManagerLogger::SetLevel(static_cast (config.loglevel.Value())); NMLOG_DEBUG("loglevel %d", config.loglevel.Value()); + /* Resolve the connectivity backend at runtime (replaces the old + * USE_CONNECTIVITY_CHECK_MGR compile-time macro). */ + m_useConnectivityCheckMgr = resolveConnectivityCheckMgrEnabled(config); + if(m_useConnectivityCheckMgr) + { + /* Stop/destroy the built-in monitor (constructed by default) so it + * does not run alongside the delegation client. */ + if(connectivityMonitor) + connectivityMonitor.reset(); + if(!connectivityClient) + connectivityClient.reset(new NetworkManagerConnectivityClient()); + NMLOG_INFO("Connectivity delegated to ConnectivityCheckMgr (runtime selection)"); + } + else + { + if(!connectivityMonitor) + connectivityMonitor.reset(new ConnectivityMonitor()); + NMLOG_INFO("Using built-in ConnectivityMonitor (runtime selection)"); + } + /* STUN configuration copy */ m_stunEndpoint = config.stun.stunEndpoint.Value(); m_stunPort = config.stun.port.Value(); @@ -194,17 +225,14 @@ namespace WPEFramework std::vector backup; NMLOG_INFO("Connectivity endpoints are empty in config; use the default"); backup.push_back("http://clients3.google.com/generate_204"); -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.setConnectivityMonitorEndpoints(backup); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + connectivityMonitor->setConnectivityMonitorEndpoints(backup); } -#ifndef USE_CONNECTIVITY_CHECK_MGR - else if (connectivityMonitor.getConnectivityMonitorEndpoints().size() < 1) + else if (!m_useConnectivityCheckMgr && connectivityMonitor && connectivityMonitor->getConnectivityMonitorEndpoints().size() < 1) { NMLOG_INFO("Use the connectivity endpoint from config"); - connectivityMonitor.setConnectivityMonitorEndpoints(connectEndpts); + connectivityMonitor->setConnectivityMonitorEndpoints(connectEndpts); } -#endif /* As all the configuration is set, lets instantiate platform */ NetworkManagerImplementation::platform_init(); @@ -214,6 +242,33 @@ namespace WPEFramework return(Core::ERROR_NONE); } + /* @brief Resolve whether internet-connectivity queries are delegated to the + * ConnectivityCheckMgr plugin. Precedence: RFC feature flag (when the + * RFC API is compiled in) -> config-line fallback -> default false. */ + bool NetworkManagerImplementation::resolveConnectivityCheckMgrEnabled(const Configuration& config) const + { + LOG_ENTRY_FUNCTION(); +#ifdef USE_RFCAPI + RFC_ParamData_t rfcParam = {0}; + WDMP_STATUS wdmpStatus = getRFCParameter(const_cast("NetworkManager"), + "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable", + &rfcParam); + if (wdmpStatus == WDMP_SUCCESS || wdmpStatus == WDMP_ERR_DEFAULT_VALUE) + { + bool enabled = (0 == strcasecmp(rfcParam.value, "true")); + NMLOG_INFO("RFC ConnectivityCheckMgr.Enable = '%s' -> %s", rfcParam.value, + enabled ? "delegate" : "internal monitor"); + return enabled; + } + NMLOG_WARNING("getRFCParameter(ConnectivityCheckMgr.Enable) failed (status=%d); using config fallback", + wdmpStatus); +#endif + bool enabled = config.useConnectivityCheckMgr.Value(); + NMLOG_INFO("ConnectivityCheckMgr delegation (config fallback) = %s", + enabled ? "enabled" : "disabled"); + return enabled; + } + /* @brief Get STUN Endpoint to be used for identifying Public IP */ uint32_t NetworkManagerImplementation::GetStunEndpoint (string &endpoint /* @out */, uint32_t& port /* @out */, uint32_t& bindTimeout /* @out */, uint32_t& cacheTimeout /* @out */) const { @@ -262,9 +317,8 @@ namespace WPEFramework { LOG_ENTRY_FUNCTION(); std::vector tmpEndpoints; -#ifndef USE_CONNECTIVITY_CHECK_MGR - tmpEndpoints = connectivityMonitor.getConnectivityMonitorEndpoints(); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + tmpEndpoints = connectivityMonitor->getConnectivityMonitorEndpoints(); endpoints = (Core::Service::Create(tmpEndpoints)); if(endpoints == nullptr) { return Core::ERROR_GENERAL; @@ -290,9 +344,8 @@ namespace WPEFramework tmpEndpoints.push_back(endpoint); } } -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.setConnectivityMonitorEndpoints(tmpEndpoints); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + connectivityMonitor->setConnectivityMonitorEndpoints(tmpEndpoints); } return Core::ERROR_NONE; } @@ -325,12 +378,17 @@ namespace WPEFramework return Core::ERROR_BAD_REQUEST; } -#ifdef USE_CONNECTIVITY_CHECK_MGR - (void)ipVersionNotSpecified; - result = connectivityClient.getInternetState(); -#else - result = connectivityMonitor.getInternetState(interface, curlIPversion, ipVersionNotSpecified); -#endif + if(m_useConnectivityCheckMgr) + { + (void)ipVersionNotSpecified; + result = connectivityClient ? connectivityClient->getInternetState() + : Exchange::INetworkManager::INTERNET_UNKNOWN; + } + else + { + result = connectivityMonitor ? connectivityMonitor->getInternetState(interface, curlIPversion, ipVersionNotSpecified) + : Exchange::INetworkManager::INTERNET_UNKNOWN; + } if (Exchange::INetworkManager::IP_ADDRESS_V6 == curlIPversion) ipversion = "IPv6"; else @@ -346,11 +404,10 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::GetCaptivePortalURI(string &uri /* @out */) const { LOG_ENTRY_FUNCTION(); -#ifdef USE_CONNECTIVITY_CHECK_MGR - uri = connectivityClient.getCaptivePortalURI(); -#else - uri = connectivityMonitor.getCaptivePortalURI(); -#endif + if(m_useConnectivityCheckMgr) + uri = connectivityClient ? connectivityClient->getCaptivePortalURI() : std::string(); + else + uri = connectivityMonitor ? connectivityMonitor->getCaptivePortalURI() : std::string(); return Core::ERROR_NONE; } @@ -700,9 +757,8 @@ namespace WPEFramework m_ethConnected.store(false); setDefaultInterface("wlan0"); // If WiFi is connected, make it the default interface // As default interface is changed to wlan0, switch connectivity monitor to initial check -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.switchToInitialCheck(); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + connectivityMonitor->switchToInitialCheck(); } else if(interface == "wlan0") { @@ -719,9 +775,8 @@ namespace WPEFramework { // When WiFi is disconnected while Ethernet is connected, we don't need to trigger connectivity monitor. // For WiFi-only state and WiFi disconnected, we should trigger connectivity monitor. -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.switchToInitialCheck(); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + connectivityMonitor->switchToInitialCheck(); } } } @@ -815,9 +870,8 @@ namespace WPEFramework if(isDefaultIface) { // As default interface is connected, switch connectivity monitor to initial check any way -#ifndef USE_CONNECTIVITY_CHECK_MGR - connectivityMonitor.switchToInitialCheck(); -#endif + if(!m_useConnectivityCheckMgr && connectivityMonitor) + connectivityMonitor->switchToInitialCheck(); } else NMLOG_DEBUG("No need to trigger connectivity monitor interface is %s", interface.c_str()); diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 70f8a85b..86a09d68 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -35,11 +35,8 @@ using namespace std; #include "INetworkManager.h" #include "NetworkManagerLogger.h" -#ifdef USE_CONNECTIVITY_CHECK_MGR -#include "NetworkManagerConnectivityClient.h" -#else #include "NetworkManagerConnectivity.h" -#endif +#include "NetworkManagerConnectivityClient.h" #include "NetworkManagerStunClient.h" #include "NetworkManagerPowerClient.h" @@ -204,6 +201,7 @@ namespace WPEFramework Add(_T("connectivity"), &connectivityConf); Add(_T("stun"), &stun); Add(_T("loglevel"), &loglevel); + Add(_T("useConnectivityCheckMgr"), &useConnectivityCheckMgr); } ~Configuration() override = default; @@ -211,6 +209,7 @@ namespace WPEFramework ConnectivityConf connectivityConf; Stun stun; Core::JSON::DecUInt32 loglevel; + Core::JSON::Boolean useConnectivityCheckMgr; }; @@ -341,6 +340,11 @@ namespace WPEFramework void platform_init(void); void platform_deinit(void); void platform_logging(const NetworkManagerLogger::LogLevel& level); + /* Resolve whether connectivity is delegated to ConnectivityCheckMgr: + * RFC flag Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable + * (when USE_RFCAPI is built in) takes precedence, then the config-line + * fallback key, then default false (built-in monitor). */ + bool resolveConnectivityCheckMgrEnabled(const Configuration& config) const; void getInitialConnectionState(void); void executeExternally(NetworkEvents event, const string commandToExecute, string& response); void threadEventRegistration(bool iarmInit, bool iarmConnect); @@ -396,11 +400,14 @@ namespace WPEFramework std::atomic m_wlanDisconnectedForSleep; std::string m_lastConnectedSSID; GMainContext *m_nmContext{nullptr}; /* isolated context for per-call NMClient creation */ -#ifdef USE_CONNECTIVITY_CHECK_MGR - mutable NetworkManagerConnectivityClient connectivityClient; -#else - mutable ConnectivityMonitor connectivityMonitor; -#endif + /* Runtime connectivity backend selection (replaces the old + * USE_CONNECTIVITY_CHECK_MGR compile-time macro). When + * m_useConnectivityCheckMgr is true, connectivity queries are + * delegated to ConnectivityCheckMgr via connectivityClient; + * otherwise the built-in connectivityMonitor is used. */ + bool m_useConnectivityCheckMgr {false}; + mutable std::unique_ptr connectivityMonitor; + mutable std::unique_ptr connectivityClient; string getDefaultInterface() const { diff --git a/tests/l2Test/rdk/l2_test_rdkproxyImpl.cpp b/tests/l2Test/rdk/l2_test_rdkproxyImpl.cpp index ebae2073..2248ab74 100644 --- a/tests/l2Test/rdk/l2_test_rdkproxyImpl.cpp +++ b/tests/l2Test/rdk/l2_test_rdkproxyImpl.cpp @@ -158,7 +158,7 @@ TEST_F(NetworkManagerImplTest, GetConnectivityTestEndpoints) { // Set up mock endpoints in the ConnectivityMonitor std::vector mockEndpoints = {"http://clients3.google.com/generate_204", "http://example.com"}; - NetworkManagerImplementation->connectivityMonitor.setConnectivityMonitorEndpoints(mockEndpoints); + NetworkManagerImplementation->connectivityMonitor->setConnectivityMonitorEndpoints(mockEndpoints); // Call GetConnectivityTestEndpoints RPC::IIteratorType* endpoints = nullptr; @@ -193,7 +193,7 @@ TEST_F(NetworkManagerImplTest, SetConnectivityTestEndpoints_EmptyEndpoints) { EXPECT_EQ(result, Core::ERROR_NONE); // Verify the endpoints were not set - std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor.getConnectivityMonitorEndpoints(); + std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor->getConnectivityMonitorEndpoints(); printf("Retrieved Endpoints Size: %zu %s\n", retrievedEndpoints.size(), retrievedEndpoints[0].c_str()); EXPECT_TRUE(retrievedEndpoints.empty() != true && retrievedEndpoints[0] == "http://clients3.google.com/generate_204"); // default endpoint should remain @@ -213,7 +213,7 @@ TEST_F(NetworkManagerImplTest, SetConnectivityTestEndpoints_ValidEndpoints) { EXPECT_EQ(result, Core::ERROR_NONE); // Verify the endpoints were set correctly - std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor.getConnectivityMonitorEndpoints(); + std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor->getConnectivityMonitorEndpoints(); EXPECT_EQ(retrievedEndpoints, validEndpoints); // Clean up @@ -233,7 +233,7 @@ TEST_F(NetworkManagerImplTest, SetConnectivityTestEndpoints_InvalidEndpoints) { EXPECT_EQ(result, Core::ERROR_NONE); // Verify the endpoints were not set - std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor.getConnectivityMonitorEndpoints(); + std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor->getConnectivityMonitorEndpoints(); EXPECT_TRUE(retrievedEndpoints.size() == 1 && retrievedEndpoints[0] == "1234567890"); // Clean up @@ -254,7 +254,7 @@ TEST_F(NetworkManagerImplTest, SetConnectivityTestEndpoints_TooManyEndpoints) { // Verify the result EXPECT_EQ(result, Core::ERROR_NONE); - std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor.getConnectivityMonitorEndpoints(); + std::vector retrievedEndpoints = NetworkManagerImplementation->connectivityMonitor->getConnectivityMonitorEndpoints(); EXPECT_EQ((int)retrievedEndpoints.size(), 12); // Clean up From 51fdfd22c28b298862602d40351483ce168bc52e Mon Sep 17 00:00:00 2001 From: Gururaaja E S R Date: Fri, 24 Jul 2026 13:54:52 -0400 Subject: [PATCH 5/7] Added enable of USE_RFCAPI in proper place --- CMakeLists.txt | 10 ++++++++++ plugin/CMakeLists.txt | 9 +++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d4cc1db..1c9e8d9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ option(ENABLE_LEGACY_PLUGINS "Enable Legacy Plugins" ON) option(USE_RDK_LOGGER "Enable RDK Logger for logging" OFF ) option(ENABLE_UNIT_TESTING "Enable unit tests" OFF) option(USE_TELEMETRY "Enable Telemetry T2 support" OFF) +option(USE_RFCAPI "Enable RFC API for TR-181 feature flag access" OFF) option(ENABLE_ETHERNET_CONNECTION_HANDLING "Enable pre-sleep Ethernet deactivation" OFF) @@ -77,6 +78,15 @@ if (USE_TELEMETRY) message("Telemetry support enabled") endif(USE_TELEMETRY) +# Optional RFC API support (for reading TR-181 RFC feature flags at runtime, e.g. +# Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable). +if (USE_RFCAPI) + find_library(RFCAPI_LIBRARY rfcapi REQUIRED) + find_path(RFCAPI_INCLUDE_DIR rfcapi.h) + add_compile_definitions(USE_RFCAPI=1) + message(STATUS "RFC API support enabled (lib=${RFCAPI_LIBRARY}, include=${RFCAPI_INCLUDE_DIR})") +endif(USE_RFCAPI) + add_subdirectory(interface) add_subdirectory(definition) add_subdirectory(plugin) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index c2acd732..ef63e917 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -93,17 +93,14 @@ target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivity.cpp NetworkManagerConnectivityClient.cpp) -# Optional RFC API support (for reading TR-181 RFC feature flags at runtime). -option(USE_RFCAPI "Enable RFC API for TR-181 feature flag access" OFF) +# Optional RFC API support. The USE_RFCAPI option, library discovery, and the +# USE_RFCAPI compile definition are declared in the top-level CMakeLists.txt +# (mirroring USE_TELEMETRY). Here we only link the library into the impl target. if(USE_RFCAPI) - find_library(RFCAPI_LIBRARY rfcapi REQUIRED) - find_path(RFCAPI_INCLUDE_DIR rfcapi.h) - target_compile_definitions(${MODULE_IMPL_NAME} PRIVATE USE_RFCAPI) target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_LIBRARY}) if(RFCAPI_INCLUDE_DIR) target_include_directories(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_INCLUDE_DIR}) endif() - message(STATUS "NetworkManager RFC API support: enabled") endif() if(ENABLE_GNOME_NETWORKMANAGER) From 9ce71029aecbbde3f107872ee57565d78ba204ca Mon Sep 17 00:00:00 2001 From: Gururaaja E S R Date: Tue, 28 Jul 2026 13:58:21 -0400 Subject: [PATCH 6/7] updated with macro USE_CONNECTIVITYCHECKMGR --- CMakeLists.txt | 15 ++++++++------- plugin/CMakeLists.txt | 25 +++++++++++++------------ plugin/NetworkManagerImplementation.cpp | 16 +++++++++++++--- plugin/NetworkManagerImplementation.h | 6 +++++- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69c35186..84431742 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ option(ENABLE_LEGACY_PLUGINS "Enable Legacy Plugins" ON) option(USE_RDK_LOGGER "Enable RDK Logger for logging" OFF ) option(ENABLE_UNIT_TESTING "Enable unit tests" OFF) option(USE_TELEMETRY "Enable Telemetry T2 support" OFF) -option(USE_RFCAPI "Enable RFC API for TR-181 feature flag access" OFF) +option(USE_CONNECTIVITYCHECKMGR "Enable ConnectivityCheckMgr delegation (compiles the delegation client and reads the TR-181 RFC feature flag via rfcapi)" OFF) option(ENABLE_ETHERNET_CONNECTION_HANDLING "Enable pre-sleep Ethernet deactivation" OFF) @@ -78,14 +78,15 @@ if (USE_TELEMETRY) message("Telemetry support enabled") endif(USE_TELEMETRY) -# Optional RFC API support (for reading TR-181 RFC feature flags at runtime, e.g. -# Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable). -if (USE_RFCAPI) +# Optional ConnectivityCheckMgr delegation. Compiles the delegation client and pulls +# in the rfcapi library used to read the TR-181 RFC feature flag at runtime, e.g. +# Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable. +if (USE_CONNECTIVITYCHECKMGR) find_library(RFCAPI_LIBRARY rfcapi REQUIRED) find_path(RFCAPI_INCLUDE_DIR rfcapi.h) - add_compile_definitions(USE_RFCAPI=1) - message(STATUS "RFC API support enabled (lib=${RFCAPI_LIBRARY}, include=${RFCAPI_INCLUDE_DIR})") -endif(USE_RFCAPI) + add_compile_definitions(USE_CONNECTIVITYCHECKMGR=1) + message(STATUS "ConnectivityCheckMgr delegation enabled (rfcapi lib=${RFCAPI_LIBRARY}, include=${RFCAPI_INCLUDE_DIR})") +endif(USE_CONNECTIVITYCHECKMGR) add_subdirectory(interface) add_subdirectory(definition) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 452346e5..6e592856 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -85,19 +85,20 @@ add_library(${MODULE_IMPL_NAME} SHARED NetworkManagerPowerClient.cpp Module.cpp) -# Connectivity backend: both the built-in ConnectivityMonitor and the -# ConnectivityCheckMgr delegation client are always compiled. Selection between -# them is made at runtime (see resolveConnectivityCheckMgrEnabled) from the RFC -# flag Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable -# with a config-line fallback. STUN is unaffected either way. +# The built-in ConnectivityMonitor is always compiled. The ConnectivityCheckMgr +# delegation client (NetworkManagerConnectivityClient.cpp) is compiled only when +# USE_CONNECTIVITYCHECKMGR is enabled; runtime selection between the two backends +# is done in resolveConnectivityCheckMgrEnabled(). STUN is unaffected either way. target_sources(${MODULE_IMPL_NAME} PRIVATE - NetworkManagerConnectivity.cpp - NetworkManagerConnectivityClient.cpp) - -# Optional RFC API support. The USE_RFCAPI option, library discovery, and the -# USE_RFCAPI compile definition are declared in the top-level CMakeLists.txt -# (mirroring USE_TELEMETRY). Here we only link the library into the impl target. -if(USE_RFCAPI) + NetworkManagerConnectivity.cpp) + +# Optional ConnectivityCheckMgr delegation. The USE_CONNECTIVITYCHECKMGR option, +# rfcapi library discovery, and the USE_CONNECTIVITYCHECKMGR compile definition are +# declared in the top-level CMakeLists.txt (mirroring USE_TELEMETRY). When enabled we +# compile the delegation client and link the rfcapi library used to read the TR-181 +# feature flag. +if(USE_CONNECTIVITYCHECKMGR) + target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerConnectivityClient.cpp) target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_LIBRARY}) if(RFCAPI_INCLUDE_DIR) target_include_directories(${MODULE_IMPL_NAME} PRIVATE ${RFCAPI_INCLUDE_DIR}) diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index be970c0f..373d5831 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -24,7 +24,7 @@ #include #include "NetworkManagerImplementation.h" -#ifdef USE_RFCAPI +#ifdef USE_CONNECTIVITYCHECKMGR #include #include "rfcapi.h" #endif @@ -187,6 +187,7 @@ namespace WPEFramework /* Resolve the connectivity backend at runtime (replaces the old * USE_CONNECTIVITY_CHECK_MGR compile-time macro). */ m_useConnectivityCheckMgr = resolveConnectivityCheckMgrEnabled(config); +#ifdef USE_CONNECTIVITYCHECKMGR if(m_useConnectivityCheckMgr) { /* Stop/destroy the built-in monitor (constructed by default) so it @@ -198,6 +199,7 @@ namespace WPEFramework NMLOG_INFO("Connectivity delegated to ConnectivityCheckMgr (runtime selection)"); } else +#endif { if(!connectivityMonitor) connectivityMonitor.reset(new ConnectivityMonitor()); @@ -265,7 +267,7 @@ namespace WPEFramework bool NetworkManagerImplementation::resolveConnectivityCheckMgrEnabled(const Configuration& config) const { LOG_ENTRY_FUNCTION(); -#ifdef USE_RFCAPI +#ifdef USE_CONNECTIVITYCHECKMGR RFC_ParamData_t rfcParam = {0}; WDMP_STATUS wdmpStatus = getRFCParameter(const_cast("NetworkManager"), "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable", @@ -279,11 +281,15 @@ namespace WPEFramework } NMLOG_WARNING("getRFCParameter(ConnectivityCheckMgr.Enable) failed (status=%d); using config fallback", wdmpStatus); -#endif bool enabled = config.useConnectivityCheckMgr.Value(); NMLOG_INFO("ConnectivityCheckMgr delegation (config fallback) = %s", enabled ? "enabled" : "disabled"); return enabled; +#else + (void)config; + NMLOG_INFO("ConnectivityCheckMgr delegation not compiled in; using built-in monitor"); + return false; +#endif } /* @brief Get STUN Endpoint to be used for identifying Public IP */ @@ -395,6 +401,7 @@ namespace WPEFramework return Core::ERROR_BAD_REQUEST; } +#ifdef USE_CONNECTIVITYCHECKMGR if(m_useConnectivityCheckMgr) { (void)ipVersionNotSpecified; @@ -402,6 +409,7 @@ namespace WPEFramework : Exchange::INetworkManager::INTERNET_UNKNOWN; } else +#endif { result = connectivityMonitor ? connectivityMonitor->getInternetState(interface, curlIPversion, ipVersionNotSpecified) : Exchange::INetworkManager::INTERNET_UNKNOWN; @@ -421,9 +429,11 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::GetCaptivePortalURI(string &uri /* @out */) const { LOG_ENTRY_FUNCTION(); +#ifdef USE_CONNECTIVITYCHECKMGR if(m_useConnectivityCheckMgr) uri = connectivityClient ? connectivityClient->getCaptivePortalURI() : std::string(); else +#endif uri = connectivityMonitor ? connectivityMonitor->getCaptivePortalURI() : std::string(); return Core::ERROR_NONE; } diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 3106e413..f618b8d2 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -38,7 +38,9 @@ using namespace std; #include "INetworkManager.h" #include "NetworkManagerLogger.h" #include "NetworkManagerConnectivity.h" +#ifdef USE_CONNECTIVITYCHECKMGR #include "NetworkManagerConnectivityClient.h" +#endif #include "NetworkManagerStunClient.h" #include "NetworkManagerPowerClient.h" @@ -394,7 +396,7 @@ namespace WPEFramework void platform_logging(const NetworkManagerLogger::LogLevel& level); /* Resolve whether connectivity is delegated to ConnectivityCheckMgr: * RFC flag Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ConnectivityCheckMgr.Enable - * (when USE_RFCAPI is built in) takes precedence, then the config-line + * (when USE_CONNECTIVITYCHECKMGR is built in) takes precedence, then the config-line * fallback key, then default false (built-in monitor). */ bool resolveConnectivityCheckMgrEnabled(const Configuration& config) const; void getInitialConnectionState(void); @@ -469,7 +471,9 @@ namespace WPEFramework * otherwise the built-in connectivityMonitor is used. */ bool m_useConnectivityCheckMgr {false}; mutable std::unique_ptr connectivityMonitor; +#ifdef USE_CONNECTIVITYCHECKMGR mutable std::unique_ptr connectivityClient; +#endif string getDefaultInterface() const { From 33217d743b9852cecb1e3a55bccd22d6111fa69e Mon Sep 17 00:00:00 2001 From: gururaajar Date: Tue, 28 Jul 2026 16:18:21 -0400 Subject: [PATCH 7/7] Added the documentation --- definition/NetworkManager.json | 30 ++++++++++++++++++++++++++++++ docs/NetworkManagerPlugin.md | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/definition/NetworkManager.json b/definition/NetworkManager.json index 84facd1e..922fdf07 100644 --- a/definition/NetworkManager.json +++ b/definition/NetworkManager.json @@ -1437,6 +1437,36 @@ ] } }, + "onRouteChange":{ + "summary": "Triggered when the default route changes and a new gateway/DNS becomes available for an interface.", + "params": { + "type": "object", + "properties": { + "interface":{ + "$ref": "#/definitions/interface" + }, + "ipversion": { + "$ref": "#/definitions/ipversion" + }, + "ipaddress": { + "$ref": "#/definitions/ipaddress" + }, + "gateway": { + "$ref": "#/definitions/gateway" + }, + "primarydns": { + "$ref": "#/definitions/primarydns" + } + }, + "required": [ + "interface", + "ipversion", + "ipaddress", + "gateway", + "primarydns" + ] + } + }, "onActiveInterfaceChange":{ "summary": "Triggered when the primary/active interface changes", "params": { diff --git a/docs/NetworkManagerPlugin.md b/docs/NetworkManagerPlugin.md index 978dd2e8..6d3a27b4 100644 --- a/docs/NetworkManagerPlugin.md +++ b/docs/NetworkManagerPlugin.md @@ -1787,6 +1787,7 @@ NetworkManager interface events: | :-------- | :-------- | | [onInterfaceStateChange](#event.onInterfaceStateChange) | Triggered when an interface state is changed | | [onAddressChange](#event.onAddressChange) | Triggered when an IP Address is assigned or lost | +| [onRouteChange](#event.onRouteChange) | Triggered when the default route changes and a new gateway/DNS becomes available for an interface | | [onActiveInterfaceChange](#event.onActiveInterfaceChange) | Triggered when the primary/active interface changes | | [onInternetStatusChange](#event.onInternetStatusChange) | Triggered when internet connection state changed | | [onAvailableSSIDs](#event.onAvailableSSIDs) | Triggered when scan completes or when scan cancelled | @@ -1858,6 +1859,38 @@ Triggered when an IP Address is assigned or lost. } ``` + +## *onRouteChange [event](#head.Notifications)* + +Triggered when the default route changes and a new gateway/DNS becomes available for an interface. + +### Parameters + +| Name | Type | Description | +| :-------- | :-------- | :-------- | +| params | object | | +| params.interface | string | An interface, such as `eth0` or `wlan0`, depending upon availability of the given interface | +| params.ipversion | string | Either IPv4 or IPv6 | +| params.ipaddress | string | The IP address | +| params.gateway | string | The gateway address | +| params.primarydns | string | The primary DNS address | + +### Example + +```json +{ + "jsonrpc": "2.0", + "method": "client.events.1.onRouteChange", + "params": { + "interface": "wlan0", + "ipversion": "IPv4", + "ipaddress": "192.168.1.101", + "gateway": "192.168.1.1", + "primarydns": "192.168.1.1" + } +} +``` + ## *onActiveInterfaceChange [event](#head.Notifications)*