From 52699d79e5dbd3bcf77c92b37d75f611004ba04b Mon Sep 17 00:00:00 2001 From: gururaajar Date: Fri, 20 Feb 2026 17:40:05 -0500 Subject: [PATCH 1/2] RDK-55826: Implement T2 Eventing in Network Manager Plugin Reason for Change: Added T2 marker for the identified T1 telemetry markers Test Procedure: Check whether the T2 events are received in the elk. Priority: P1 Risks: Medium Signed-off-by: Gururaaja ESR --- CMakeLists.txt | 6 ++++ plugin/CMakeLists.txt | 4 +++ plugin/NetworkManager.cpp | 4 +++ plugin/NetworkManagerImplementation.cpp | 35 ++++++++++++++++++++++++ plugin/NetworkManagerImplementation.h | 5 ++++ plugin/gnome/NetworkManagerGnomeWIFI.cpp | 5 +++- 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f774427b..3cf6ab19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ get_directory_property(SEVICES_DEFINES COMPILE_DEFINITIONS) 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" ON) add_subdirectory(interface) @@ -71,3 +72,8 @@ if(ENABLE_UNIT_TESTING) add_subdirectory(tests/l2Test) endif(ENABLE_UNIT_TESTING) +if (USE_TELEMETRY) + find_package(T2 REQUIRED) + add_definitions(-DUSE_TELEMETRY) + message("Telemetry support enabled") +endif(USE_TELEMETRY) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index abfd9998..a18e31ca 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -141,6 +141,10 @@ if (USE_RDK_LOGGER) target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${RDKLOGGER_LIBRARIES}) endif (USE_RDK_LOGGER) +if (USE_TELEMETRY) + target_link_libraries(${MODULE_NAME} PRIVATE ${T2_LIBRARIES}) +endif (USE_TELEMETRY) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) install(TARGETS ${MODULE_IMPL_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) diff --git a/plugin/NetworkManager.cpp b/plugin/NetworkManager.cpp index 1049e503..73bf899e 100644 --- a/plugin/NetworkManager.cpp +++ b/plugin/NetworkManager.cpp @@ -124,6 +124,10 @@ namespace WPEFramework message = _T("Failed to initialize NetworkManager"); } + #if USE_TELEMETRY + // Initialize Telemtry T2 for NwMgrPlugin + t2_init("NwMgrPlugin"); + #endif // Success return message; } diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index cd616c54..00df9b4d 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -357,6 +357,10 @@ namespace WPEFramework interface = m_defaultInterface; ipaddress = result.public_ip; +#if USE_TELEMETRY + if(ipversion == "IPv4") + logTelemetry("NM_PUBLIC_IPV4", ipaddress); +#endif return Core::ERROR_NONE; } else @@ -710,6 +714,9 @@ namespace WPEFramework for (const auto callback : _notificationCallbacks) { callback->onActiveInterfaceChange(prevActiveInterface, currentActiveinterface); } +#if USE_TELEMETRY + logTelemetry("NM_INTERFACE_STATUS", "Interface changed to " + currentActiveinterface); +#endif _notificationLock.Unlock(); } @@ -756,9 +763,22 @@ namespace WPEFramework { _notificationLock.Lock(); NMLOG_INFO("Posting onInternetStatusChange with current state as %u", (unsigned)currState); +#if USE_TELEMETRY + // Log error only when ethernet is down and there's no internet + if(currState == Exchange::INetworkManager::INTERNET_NOT_AVAILABLE && + !m_ethConnected.load() && + prevState != Exchange::INetworkManager::INTERNET_NOT_AVAILABLE) + { + logTelemetry("NM_ETHERNET_FAILED", "Ethernet is down, no internet"); + } +#endif for (const auto callback : _notificationCallbacks) { callback->onInternetStatusChange(prevState, currState, interface); } +#if USE_TELEMETRY + string stateStr = Core::EnumerateType(currState).Data(); + logTelemetry("NM_INTERNET_STATUS", stateStr); +#endif _notificationLock.Unlock(); } @@ -1107,6 +1127,10 @@ namespace WPEFramework _notificationLock.Lock(); NMLOG_INFO("Posting onWiFiStateChange (%d)", state); +#if USE_TELEMETRY + string stateStr = Core::EnumerateType(state).Data(); + logTelemetry("NM_WIFI_STATUS", stateStr); +#endif for (const auto callback : _notificationCallbacks) { callback->onWiFiStateChange(state); } @@ -1122,5 +1146,16 @@ namespace WPEFramework } _notificationLock.Unlock(); } + + void NetworkManagerImplementation::logTelemetry(const std::string& eventName, const std::string& message) + { +#if USE_TELEMETRY + T2ERROR t2error = t2_event_s(eventName.c_str(), (char*)message.c_str()); + if (t2error != T2ERROR_SUCCESS) { + NMLOG_ERROR("t2_event_s(\"%s\", \"%s\") failed with error %d", + eventName.c_str(), message.c_str(), t2error); + } +#endif + } } } diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 565d7ee9..1314fb54 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -34,6 +34,10 @@ using namespace std; #include "NetworkManagerConnectivity.h" #include "NetworkManagerStunClient.h" +#if USE_TELEMETRY +#include +#endif + /* * Receiver thermal noise + BW factor + assumed noise figure (NF) (dB) * for a 20MHz channel, @@ -269,6 +273,7 @@ namespace WPEFramework void ReportAvailableSSIDs(const JsonArray &arrayofWiFiScanResults); void ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state); void ReportWiFiSignalQualityChange(const string ssid, const int strength, const int noise, const int snr, const Exchange::INetworkManager::WiFiSignalQuality quality); + void logTelemetry(const std::string& eventName, const std::string& message); private: void platform_init(void); diff --git a/plugin/gnome/NetworkManagerGnomeWIFI.cpp b/plugin/gnome/NetworkManagerGnomeWIFI.cpp index b6583482..c0fb7be4 100644 --- a/plugin/gnome/NetworkManagerGnomeWIFI.cpp +++ b/plugin/gnome/NetworkManagerGnomeWIFI.cpp @@ -945,7 +945,10 @@ namespace WPEFramework std::string activeSSID{}; NMLOG_DEBUG("wifi connect ssid: %s, security %d persist %d", ssidInfoParam.ssid.c_str(), ssidInfoParam.security, ssidInfoParam.persist); - +#if USE_TELEMETRY + if(ssidInfoParam.ssid.empty()) + _instance->logTelemetry("NM_WIFI_SSID_NULL", "WiFi SSID is NULL"); +#endif Exchange::INetworkManager::WiFiConnectTo ssidInfo = ssidInfoParam; m_isSuccess = false; if(!createClientNewConnection()) From ff035cb90038c3800ae47b75040ae6b9e8b1580d Mon Sep 17 00:00:00 2001 From: gururaajar Date: Fri, 20 Feb 2026 17:40:05 -0500 Subject: [PATCH 2/2] RDK-55826: Implement T2 Eventing in Network Manager Plugin Reason for Change: Added T2 marker for the identified T1 telemetry markers Test Procedure: Check whether the T2 events are received in the elk. Priority: P1 Risks: Medium Signed-off-by: Gururaaja ESR --- CMakeLists.txt | 6 ++ plugin/CMakeLists.txt | 4 + plugin/NetworkManager.cpp | 4 + plugin/NetworkManagerImplementation.cpp | 40 +++++++++ plugin/NetworkManagerImplementation.h | 5 ++ plugin/gnome/NetworkManagerGnomeEvents.cpp | 22 ++++- plugin/gnome/NetworkManagerGnomeUtils.cpp | 95 ++++++++++++++++++++++ plugin/gnome/NetworkManagerGnomeUtils.h | 2 + plugin/gnome/NetworkManagerGnomeWIFI.cpp | 5 +- 9 files changed, 181 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f774427b..3cf6ab19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ get_directory_property(SEVICES_DEFINES COMPILE_DEFINITIONS) 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" ON) add_subdirectory(interface) @@ -71,3 +72,8 @@ if(ENABLE_UNIT_TESTING) add_subdirectory(tests/l2Test) endif(ENABLE_UNIT_TESTING) +if (USE_TELEMETRY) + find_package(T2 REQUIRED) + add_definitions(-DUSE_TELEMETRY) + message("Telemetry support enabled") +endif(USE_TELEMETRY) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index abfd9998..a18e31ca 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -141,6 +141,10 @@ if (USE_RDK_LOGGER) target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${RDKLOGGER_LIBRARIES}) endif (USE_RDK_LOGGER) +if (USE_TELEMETRY) + target_link_libraries(${MODULE_NAME} PRIVATE ${T2_LIBRARIES}) +endif (USE_TELEMETRY) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) install(TARGETS ${MODULE_IMPL_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) diff --git a/plugin/NetworkManager.cpp b/plugin/NetworkManager.cpp index 1049e503..73bf899e 100644 --- a/plugin/NetworkManager.cpp +++ b/plugin/NetworkManager.cpp @@ -124,6 +124,10 @@ namespace WPEFramework message = _T("Failed to initialize NetworkManager"); } + #if USE_TELEMETRY + // Initialize Telemtry T2 for NwMgrPlugin + t2_init("NwMgrPlugin"); + #endif // Success return message; } diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index cd616c54..6b501802 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -357,6 +357,11 @@ namespace WPEFramework interface = m_defaultInterface; ipaddress = result.public_ip; +#if USE_TELEMETRY + NMLOG_LOG("****** GURU: sending T2 event for NM_PUBLIC_IPV4 = %s ******", ipaddress); + if(ipversion == "IPv4") + logTelemetry("NM_PUBLIC_IPV4", ipaddress); +#endif return Core::ERROR_NONE; } else @@ -710,6 +715,10 @@ namespace WPEFramework for (const auto callback : _notificationCallbacks) { callback->onActiveInterfaceChange(prevActiveInterface, currentActiveinterface); } +#if USE_TELEMETRY + NMLOG_LOG("****** GURU: sending T2 event for NM_INTERFACE_STATUS = %s ******", currentActiveinterface.c_str()); + logTelemetry("NM_INTERFACE_STATUS", "Interface changed to " + currentActiveinterface); +#endif _notificationLock.Unlock(); } @@ -756,9 +765,24 @@ namespace WPEFramework { _notificationLock.Lock(); NMLOG_INFO("Posting onInternetStatusChange with current state as %u", (unsigned)currState); +#if USE_TELEMETRY + // Log error only when ethernet is down and there's no internet + if(currState == Exchange::INetworkManager::INTERNET_NOT_AVAILABLE && + !m_ethConnected.load() && + prevState != Exchange::INetworkManager::INTERNET_NOT_AVAILABLE) + { + NMLOG_LOG("****** GURU: sending T2 event for NM_ETHERNET_FAILED = %s ******", "Ethernet is down, no internet"); + logTelemetry("NM_ETHERNET_FAILED", "Ethernet is down, no internet"); + } +#endif for (const auto callback : _notificationCallbacks) { callback->onInternetStatusChange(prevState, currState, interface); } +#if USE_TELEMETRY + string stateStr = Core::EnumerateType(currState).Data(); + NMLOG_LOG("****** GURU: sending T2 event for NM_INTERNET_STATUS = %s ******", stateStr.c_str()); + logTelemetry("NM_INTERNET_STATUS", stateStr); +#endif _notificationLock.Unlock(); } @@ -1107,6 +1131,11 @@ namespace WPEFramework _notificationLock.Lock(); NMLOG_INFO("Posting onWiFiStateChange (%d)", state); +#if USE_TELEMETRY + string stateStr = Core::EnumerateType(state).Data(); + NMLOG_LOG("****** GURU: sending T2 event for NM_WIFI_STATUS = %s ******", stateStr.c_str()); + logTelemetry("NM_WIFI_STATUS", stateStr); +#endif for (const auto callback : _notificationCallbacks) { callback->onWiFiStateChange(state); } @@ -1122,5 +1151,16 @@ namespace WPEFramework } _notificationLock.Unlock(); } + + void NetworkManagerImplementation::logTelemetry(const std::string& eventName, const std::string& message) + { +#if USE_TELEMETRY + T2ERROR t2error = t2_event_s(eventName.c_str(), (char*)message.c_str()); + if (t2error != T2ERROR_SUCCESS) { + NMLOG_ERROR("t2_event_s(\"%s\", \"%s\") failed with error %d", + eventName.c_str(), message.c_str(), t2error); + } +#endif + } } } diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index 565d7ee9..1314fb54 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -34,6 +34,10 @@ using namespace std; #include "NetworkManagerConnectivity.h" #include "NetworkManagerStunClient.h" +#if USE_TELEMETRY +#include +#endif + /* * Receiver thermal noise + BW factor + assumed noise figure (NF) (dB) * for a 20MHz channel, @@ -269,6 +273,7 @@ namespace WPEFramework void ReportAvailableSSIDs(const JsonArray &arrayofWiFiScanResults); void ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state); void ReportWiFiSignalQualityChange(const string ssid, const int strength, const int noise, const int snr, const Exchange::INetworkManager::WiFiSignalQuality quality); + void logTelemetry(const std::string& eventName, const std::string& message); private: void platform_init(void); diff --git a/plugin/gnome/NetworkManagerGnomeEvents.cpp b/plugin/gnome/NetworkManagerGnomeEvents.cpp index 90f9b03f..193b8f90 100644 --- a/plugin/gnome/NetworkManagerGnomeEvents.cpp +++ b/plugin/gnome/NetworkManagerGnomeEvents.cpp @@ -271,8 +271,28 @@ namespace WPEFramework } if (nm_ip_address_get_family(address) == AF_INET) { const char *ipAddress = nm_ip_address_get_address(address); - if(ipAddress != NULL) + if(ipAddress != NULL) { GnomeNetworkManagerEvents::onAddressChangeCb(iface, ipAddress, true, false); + // Get gateway MAC address for WiFi after IP is acquired + if(ifname == nmUtils::wlanIface() || ifname == nmUtils::ethIface()) { + static std::map gatewayMacCache; + NMClient *client = nm_object_get_client(NM_OBJECT(device)); + if (client != NULL) { + std::string gatewayMac = nmUtils::getGatewayMacAddress(client, ifname); + if (!gatewayMac.empty()) { + // Only log when MAC changes or is first time + if (gatewayMacCache[ifname] != gatewayMac) { + gatewayMacCache[ifname] = gatewayMac; + NMLOG_INFO("******** GURU: gatewayMacCache[%s] : %s ********", ifname.c_str(), gatewayMacCache[ifname].c_str()); +#if USE_TELEMETRY + NMLOG_INFO("******** GURU: connected - Gateway MAC: %s ********", gatewayMac.c_str()); + logTelemetry("NM_GW_MAC", gatewayMac); +#endif + } + } + } + } + } } } } diff --git a/plugin/gnome/NetworkManagerGnomeUtils.cpp b/plugin/gnome/NetworkManagerGnomeUtils.cpp index d175b27a..0818d908 100644 --- a/plugin/gnome/NetworkManagerGnomeUtils.cpp +++ b/plugin/gnome/NetworkManagerGnomeUtils.cpp @@ -389,5 +389,100 @@ namespace WPEFramework return false; } + std::string nmUtils::resolveGatewayMac(const std::string& gatewayIp) + { + std::string mac = ""; + std::string arpFile = "/proc/net/arp"; + std::ifstream file(arpFile); + std::string line; + + if (!file.is_open()) { + NMLOG_ERROR("Failed to open %s", arpFile.c_str()); + return mac; + } + + // Skip header + std::getline(file, line); + + while (std::getline(file, line)) { + std::istringstream iss(line); + std::string ip, hwType, flags, hwAddr; + + if (iss >> ip >> hwType >> flags >> hwAddr) { + if (ip == gatewayIp && hwAddr != "00:00:00:00:00:00") { + mac = hwAddr; + NMLOG_INFO("Resolved gateway IP %s to MAC %s", gatewayIp.c_str(), mac.c_str()); + break; + } + } + } + + if (mac.empty()) { + NMLOG_WARNING("Could not resolve gateway IP %s to MAC address", gatewayIp.c_str()); + } + + return mac; + } + + std::string nmUtils::getGatewayMacAddress(NMClient* client, const std::string& interface) + { + std::string gatewayMac = ""; + + if (client == NULL) { + NMLOG_ERROR("NMClient is NULL"); + return gatewayMac; + } + + if (interface.empty()) { + NMLOG_ERROR("Interface name is empty"); + return gatewayMac; + } + + // Get all active connections and find the one for our interface + const GPtrArray *activeConnections = nm_client_get_active_connections(client); + if (!activeConnections) { + NMLOG_WARNING("No active connections found"); + return gatewayMac; + } + + for (guint i = 0; i < activeConnections->len; i++) { + NMActiveConnection *activeConn = NM_ACTIVE_CONNECTION(g_ptr_array_index(activeConnections, i)); + if (!activeConn) continue; + + // Get devices for this connection + const GPtrArray *devices = nm_active_connection_get_devices(activeConn); + if (!devices) continue; + + // Check if this connection belongs to our interface + for (guint j = 0; j < devices->len; j++) { + NMDevice *device = NM_DEVICE(g_ptr_array_index(devices, j)); + if (!device) continue; + + const char *ifname = nm_device_get_iface(device); + if (ifname && interface == ifname) { + // Found the connection for our interface + NMIPConfig *ip4Config = nm_active_connection_get_ip4_config(activeConn); + if (ip4Config) { + const char *gateway = nm_ip_config_get_gateway(ip4Config); + if (gateway) { + NMLOG_DEBUG("Found gateway IP for %s: %s", interface.c_str(), gateway); + // Use ARP to resolve gateway IP to MAC address + gatewayMac = resolveGatewayMac(gateway); + return gatewayMac; + } else { + NMLOG_WARNING("No gateway found for %s", interface.c_str()); + } + } else { + NMLOG_WARNING("No IPv4 configuration found for %s", interface.c_str()); + } + return gatewayMac; + } + } + } + + NMLOG_WARNING("No active connection found for interface %s", interface.c_str()); + return gatewayMac; + } + } // Plugin } // WPEFramework diff --git a/plugin/gnome/NetworkManagerGnomeUtils.h b/plugin/gnome/NetworkManagerGnomeUtils.h index b9632d2e..dbfb24b1 100644 --- a/plugin/gnome/NetworkManagerGnomeUtils.h +++ b/plugin/gnome/NetworkManagerGnomeUtils.h @@ -50,6 +50,8 @@ namespace WPEFramework static bool isInterfaceEnabled(const std::string& interface); static bool writePersistentHostname(const std::string& hostname); static bool readPersistentHostname(std::string& hostname); + static std::string resolveGatewayMac(const std::string& gatewayIp); + static std::string getGatewayMacAddress(NMClient* client, const std::string& interface); }; } } diff --git a/plugin/gnome/NetworkManagerGnomeWIFI.cpp b/plugin/gnome/NetworkManagerGnomeWIFI.cpp index b6583482..c0fb7be4 100644 --- a/plugin/gnome/NetworkManagerGnomeWIFI.cpp +++ b/plugin/gnome/NetworkManagerGnomeWIFI.cpp @@ -945,7 +945,10 @@ namespace WPEFramework std::string activeSSID{}; NMLOG_DEBUG("wifi connect ssid: %s, security %d persist %d", ssidInfoParam.ssid.c_str(), ssidInfoParam.security, ssidInfoParam.persist); - +#if USE_TELEMETRY + if(ssidInfoParam.ssid.empty()) + _instance->logTelemetry("NM_WIFI_SSID_NULL", "WiFi SSID is NULL"); +#endif Exchange::INetworkManager::WiFiConnectTo ssidInfo = ssidInfoParam; m_isSuccess = false; if(!createClientNewConnection())