diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index c7c7bfeb..5a1c27d8 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -47,7 +47,7 @@ target_link_libraries(${PROXYLIB} PRIVATE CompileSettingsDebug::CompileSettingsDebug) set_target_properties(${PROXYLIB} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE) diff --git a/legacy/CMakeLists.txt b/legacy/CMakeLists.txt index e3b11dd7..79a45990 100644 --- a/legacy/CMakeLists.txt +++ b/legacy/CMakeLists.txt @@ -27,6 +27,9 @@ set(PLUGIN_LEGACY_WIFI ${NAMESPACE}WiFiManager) set(PLUGIN_LEGACY_NW_STARTUPORDER "35" CACHE STRING "To configure startup order of Legacy Network plugin") set(PLUGIN_LEGACY_WIFI_STARTUPORDER "35" CACHE STRING "To configure startup order of Legacy WiFi plugin") +set(PLUGIN_LEGACY_NW_AUTOSTART "false" CACHE STRING "The autostart of Legacy Network plugin") +set(PLUGIN_LEGACY_WIFI_AUTOSTART "false" CACHE STRING "The autostart of Legacy WiFi plugin") + set(PLUGIN_BUILD_REFERENCE ${PROJECT_VERSION} CACHE STRING "To Set the Hash for the plugin") add_definitions(-DPLUGIN_BUILD_REFERENCE=${PLUGIN_BUILD_REFERENCE}) @@ -53,7 +56,7 @@ if (USE_RDK_LOGGER) endif (USE_RDK_LOGGER) set_target_properties(${PLUGIN_LEGACY_NETWORK} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES) install(TARGETS ${PLUGIN_LEGACY_NETWORK} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) @@ -71,7 +74,7 @@ if (USE_RDK_LOGGER) endif (USE_RDK_LOGGER) set_target_properties(${PLUGIN_LEGACY_WIFI} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES) install(TARGETS ${PLUGIN_LEGACY_WIFI} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) diff --git a/legacy/LegacyNetworkAPIs.conf.in b/legacy/LegacyNetworkAPIs.conf.in index 39cf67b9..70bef4cd 100644 --- a/legacy/LegacyNetworkAPIs.conf.in +++ b/legacy/LegacyNetworkAPIs.conf.in @@ -1,4 +1,4 @@ precondition = ["Platform"] callsign = "org.rdk.Network" -autostart = "false" +autostart = "@PLUGIN_LEGACY_NW_AUTOSTART@" startuporder = "@PLUGIN_LEGACY_NW_STARTUPORDER@" diff --git a/legacy/LegacyNetworkAPIs.config b/legacy/LegacyNetworkAPIs.config deleted file mode 100644 index 34c60c67..00000000 --- a/legacy/LegacyNetworkAPIs.config +++ /dev/null @@ -1,4 +0,0 @@ -set (autostart false) -set (preconditions Platform) -set (callsign "org.rdk.Network") -set (startuporder ${PLUGIN_LEGACY_NW_STARTUPORDER}) diff --git a/legacy/LegacyWiFiManagerAPIs.conf.in b/legacy/LegacyWiFiManagerAPIs.conf.in index 02f46112..92beadbb 100644 --- a/legacy/LegacyWiFiManagerAPIs.conf.in +++ b/legacy/LegacyWiFiManagerAPIs.conf.in @@ -1,4 +1,4 @@ precondition = ["Platform"] callsign = "org.rdk.Wifi" -autostart = "false" +autostart = "@PLUGIN_LEGACY_WIFI_AUTOSTART@" startuporder = "@PLUGIN_LEGACY_WIFI_STARTUPORDER@" diff --git a/legacy/LegacyWiFiManagerAPIs.config b/legacy/LegacyWiFiManagerAPIs.config deleted file mode 100644 index 7aa4dfb3..00000000 --- a/legacy/LegacyWiFiManagerAPIs.config +++ /dev/null @@ -1,4 +0,0 @@ -set (autostart false) -set (preconditions Platform) -set (callsign "org.rdk.Wifi") -set (startuporder ${PLUGIN_LEGACY_WIFI_STARTUPORDER}) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 6090b8f1..32d065dc 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -49,9 +49,10 @@ else() find_package(IARMBus REQUIRED) endif () -set(PLUGIN_NETWORKMANAGER_LOGLEVEL "5" CACHE STRING "To configure default loglevel NetworkManager plugin") +set(PLUGIN_NETWORKMANAGER_LOGLEVEL "3" 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_AUTOSTART "false" CACHE STRING "Set the default AutoStart of NetworkManager Plugin") set(PLUGIN_BUILD_REFERENCE ${PROJECT_VERSION} CACHE STRING "To Set the Hash for the plugin") add_definitions(-DPLUGIN_BUILD_REFERENCE=${PLUGIN_BUILD_REFERENCE}) @@ -71,7 +72,7 @@ target_link_libraries(${MODULE_NAME} PRIVATE ) set_target_properties(${MODULE_NAME} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE) @@ -128,7 +129,7 @@ else() endif() set_target_properties(${MODULE_IMPL_NAME} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE) diff --git a/plugin/NetworkManager.conf.in b/plugin/NetworkManager.conf.in index b4876296..ac3127cc 100644 --- a/plugin/NetworkManager.conf.in +++ b/plugin/NetworkManager.conf.in @@ -1,6 +1,6 @@ callsign= "org.rdk.NetworkManager" startuporder = "@PLUGIN_NETWORKMANAGER_STARTUPORDER@" -autostart = "false" +autostart = "@PLUGIN_NETWORKMANAGER_AUTOSTART@" process= JSON() process.add("outofprocess", "true") diff --git a/plugin/NetworkManager.config b/plugin/NetworkManager.config deleted file mode 100644 index 59563509..00000000 --- a/plugin/NetworkManager.config +++ /dev/null @@ -1,27 +0,0 @@ -set(callsign "org.rdk.NetworkManager") -set (startuporder ${PLUGIN_NETWORKMANAGER_STARTUPORDER}) -set (autostart false) - -map() - key(root) - map() - kv(outofprocess true) - end() - key(connectivity) - map() - kv(endpoint_1 ${PLUGIN_NETWORKMANAGER_CONN_ENDPOINT_1}) - kv(endpoint_2 ${PLUGIN_NETWORKMANAGER_CONN_ENDPOINT_2}) - kv(endpoint_3 ${PLUGIN_NETWORKMANAGER_CONN_ENDPOINT_3}) - kv(endpoint_4 ${PLUGIN_NETWORKMANAGER_CONN_ENDPOINT_4}) - kv(endpoint_5 ${PLUGIN_NETWORKMANAGER_CONN_ENDPOINT_5}) - kv(interval, @PLUGIN_NETWORKMANAGER_CONN_MONITOR_INTERVAL@) - end() - key(stun) - map() - kv(endpoint, ${PLUGIN_NETWORKMANAGER_STUN_ENDPOINT}) - kv(port, PLUGIN_NETWORKMANAGER_STUN_PORT) - kv(interval, 30) - end() - kv(loglevel, 3) -end() -ans(configuration) diff --git a/plugin/NetworkManager.cpp b/plugin/NetworkManager.cpp index 1049e503..10ed4598 100644 --- a/plugin/NetworkManager.cpp +++ b/plugin/NetworkManager.cpp @@ -84,12 +84,6 @@ namespace WPEFramework // Still running inside the main WPEFramework process - the child process will have now been spawned and registered if necessary if (_networkManager != nullptr) { - - // Set the plugin log level - Exchange::INetworkManager::Logging _loglevel; - _networkManager->GetLogLevel(_loglevel); - NetworkManagerLogger::SetLevel(static_cast (_loglevel)); - // Register Notifications SYSLOG(Logging::Startup, (_T("Registering Notification to NetworkManager"))); _networkManager->Register(&_notification); @@ -103,6 +97,12 @@ namespace WPEFramework { SYSLOG(Logging::Startup, (_T("Configuring successful"))); } + + // Set the plugin log level + Exchange::INetworkManager::Logging _loglevel; + _networkManager->GetLogLevel(_loglevel); + NetworkManagerLogger::SetLevel(static_cast (_loglevel)); + // Register all custom JSON-RPC methods SYSLOG(Logging::Startup, (_T("Registering JSONRPC Methods"))); RegisterAllMethods(); diff --git a/plugin/NetworkManagerImplementation.cpp b/plugin/NetworkManagerImplementation.cpp index c0120534..942d2827 100644 --- a/plugin/NetworkManagerImplementation.cpp +++ b/plugin/NetworkManagerImplementation.cpp @@ -67,6 +67,12 @@ namespace WPEFramework NetworkManagerLogger::Init(); NMLOG_INFO((_T("NWMgrPlugin Out-Of-Process Instantiation; SHA: " _T(EXPAND_AND_QUOTE(PLUGIN_BUILD_REFERENCE))))); m_processMonThread = std::thread(&NetworkManagerImplementation::processMonitor, this, NM_PROCESS_MONITOR_INTERVAL_SEC); + + /* Start dedicated event dispatch thread */ + m_eventThreadStop.store(false); + m_eventThread = std::thread(&NetworkManagerImplementation::eventThreadFunction, this); + NMLOG_INFO("Event dispatch thread started"); + #if USE_TELEMETRY // Initialize Telemetry T2 for NwMgrPlugin t2_init("NwMgrPlugin"); @@ -87,6 +93,17 @@ namespace WPEFramework /* Stop WiFi Signal Monitoring */ stopWiFiSignalQualityMonitor(); + /* Stop event dispatch thread */ + { + std::unique_lock lock(m_eventMutex); + m_eventThreadStop.store(true); + m_eventCondVar.notify_one(); + } + if (m_eventThread.joinable()) { + m_eventThread.join(); + NMLOG_INFO("Event dispatch thread stopped"); + } + { std::unique_lock lock(m_processMonMutex); m_processMonThreadStop.store(true); @@ -338,6 +355,7 @@ namespace WPEFramework /* @brief Get the active Interface used for external world communication */ uint32_t NetworkManagerImplementation::GetPrimaryInterface (string& interface /* @out */) { + LOG_ENTRY_FUNCTION(); if(m_ethEnabled.load() && m_ethConnected.load()) interface = "eth0"; else if(m_wlanEnabled.load() && m_wlanConnected.load()) @@ -397,6 +415,7 @@ namespace WPEFramework /* @brief Set the network manager plugin log level */ uint32_t NetworkManagerImplementation::SetLogLevel(const Logging& level /* @in */) { + LOG_ENTRY_FUNCTION(); NetworkManagerLogger::SetLevel(static_cast(level)); platform_logging(static_cast(level)); NMLOG_DEBUG("loglevel %d", level); @@ -406,6 +425,7 @@ namespace WPEFramework /* @brief Get the network manager plugin log level */ uint32_t NetworkManagerImplementation::GetLogLevel(Logging& level /* @out */) { + LOG_ENTRY_FUNCTION(); LogLevel inLevel; NetworkManagerLogger::GetLevel(inLevel); @@ -416,6 +436,7 @@ namespace WPEFramework /* @brief Request for ping and get the response in as event. The GUID used in the request will be returned in the event. */ uint32_t NetworkManagerImplementation::Ping (const string ipversion /* @in */, const string endpoint /* @in */, const uint32_t noOfRequest /* @in */, const uint16_t timeOutInSeconds /* @in */, const string guid /* @in */, string& response /* @out */) { + LOG_ENTRY_FUNCTION(); char cmd[100] = ""; string tempResult = ""; if (endpoint.empty() || (ipversion != "IPv4" && ipversion != "IPv6")) @@ -447,6 +468,7 @@ namespace WPEFramework /* @brief Request for trace get the response in as event. The GUID used in the request will be returned in the event. */ uint32_t NetworkManagerImplementation::Trace (const string ipversion /* @in */, const string endpoint /* @in */, const uint32_t noOfRequest /* @in */, const string guid /* @in */, string& response /* @out */) { + LOG_ENTRY_FUNCTION(); char cmd[256] = ""; string tempResult = ""; if (endpoint.empty() || (ipversion != "IPv4" && ipversion != "IPv6")) @@ -477,6 +499,7 @@ namespace WPEFramework void NetworkManagerImplementation::executeExternally(NetworkEvents event, const string commandToExecute, string& response) { + LOG_ENTRY_FUNCTION(); FILE *pipe = NULL; string output{}; char buffer[1024]; @@ -574,7 +597,7 @@ namespace WPEFramework } pingResult.ToString(response); - NMLOG_INFO("Response is, %s", response.c_str()); + NMLOG_DEBUG("Response is, %s", response.c_str()); } else if (NETMGR_TRACE == event) { @@ -592,15 +615,16 @@ namespace WPEFramework pclose(pipe); list.ToString(response); - NMLOG_INFO("Response is, %s", response.c_str()); + NMLOG_DEBUG("Response is, %s", response.c_str()); } return; } - void NetworkManagerImplementation::filterScanResults(JsonArray &ssids, - const std::vector& filterSsidslist, - const std::vector& filterFrequencies) + void NetworkManagerImplementation::filterScanResults(JsonArray &ssids, + const std::vector& filterSsidslist, + const std::vector& filterFrequencies) { + LOG_ENTRY_FUNCTION(); JsonArray result; double filterFreq = 0.0; std::unordered_set scanForSsidsSet(filterSsidslist.begin(), filterSsidslist.end()); @@ -669,6 +693,150 @@ namespace WPEFramework return Core::ERROR_NONE; } + + void NetworkManagerImplementation::enqueueEvent(NMPublishEvents event, EventDataVariant&& data) + { + LOG_ENTRY_FUNCTION(); + { + std::lock_guard lock(m_eventMutex); + m_eventQueue.push({event, std::move(data)}); + NMLOG_DEBUG("Event %d queued, queue size: %zu", event, m_eventQueue.size()); + } + m_eventCondVar.notify_one(); + } + + void NetworkManagerImplementation::eventThreadFunction() + { + NMLOG_INFO("Event thread started"); + + while (!m_eventThreadStop.load()) { + std::unique_lock lock(m_eventMutex); + + // Wait for events or stop signal + m_eventCondVar.wait(lock, [this] { + return !m_eventQueue.empty() || m_eventThreadStop.load(); + }); + + // Process all queued events + while (!m_eventQueue.empty() && !m_eventThreadStop.load()) { + EventData eventData = std::move(m_eventQueue.front()); + m_eventQueue.pop(); + + // Unlock while processing to avoid blocking new events + lock.unlock(); + + NMLOG_DEBUG("Processing event %d from queue", eventData.event); + dispatchEvent(eventData.event, eventData.data); + + lock.lock(); + } + } + + // Log if events were discarded during shutdown + if (!m_eventQueue.empty()) { + NMLOG_WARNING("Event thread shutting down with %zu events discarded", m_eventQueue.size()); + } + + NMLOG_INFO("Event thread exiting"); + } + + void NetworkManagerImplementation::dispatchEvent(NMPublishEvents event, const EventDataVariant& data) + { + LOG_ENTRY_FUNCTION(); + std::list callbacks; + /* + * Fix: holding of _notificationLock lock until the all the subscribers being notified n returning is expensive and could lead to deadlock. + * So, Acquire the mutex, increase the ref count n release it. We Can release the ref after callback invocation. This is safer + */ + _notificationLock.Lock(); + for (auto* tmpCB : _notificationCallbacks) { + tmpCB->AddRef(); + callbacks.push_back(tmpCB); + } + _notificationLock.Unlock(); + + switch(event) + { + case NM_ON_INTERFACESTATE_CHANGE: + { + NMLOG_INFO("Publishing onInterfaceStateChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onInterfaceStateChange(eventData.state, eventData.interface); + callback->Release(); + } + } + break; + case NM_ON_ACTIVEINTERFACE_CHANGE: + { + NMLOG_INFO("Publishing onActiveInterfaceChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onActiveInterfaceChange(eventData.prevActiveInterface, eventData.currentActiveInterface); + callback->Release(); + } + } + break; + case NM_ON_IPADDRESS_CHANGE: + { + NMLOG_INFO("Publishing onIPAddressChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onIPAddressChange(eventData.interface, eventData.ipversion, eventData.ipaddress, eventData.status); + callback->Release(); + } + } + break; + case NM_ON_INTERNETSTATUS_CHANGE: + { + NMLOG_INFO("Publishing onInternetStatusChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onInternetStatusChange(eventData.prevState, eventData.currState, eventData.interface); + callback->Release(); + } + } + break; + case NM_ON_AVAILABLESSIDS: + { + NMLOG_INFO("Publishing onAvailableSSIDs Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onAvailableSSIDs(eventData.jsonResult); + callback->Release(); + } + } + break; + case NM_ON_WIFISTATE_CHANGE: + { + NMLOG_INFO("Publishing onWiFiStateChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onWiFiStateChange(eventData.state); + callback->Release(); + } + } + break; + case NM_ON_WIFISIGNALQUALITY_CHANGE: + { + NMLOG_INFO("Publishing onWiFiSignalQualityChange Event"); + const auto& eventData = std::get(data); + for (const auto callback : callbacks) { + callback->onWiFiSignalQualityChange(eventData.ssid, eventData.strength, eventData.noise, eventData.snr, eventData.quality); + callback->Release(); + } + } + break; + default: + { + for (const auto callback : callbacks) { + callback->Release(); + } + } + break; + } + } + void NetworkManagerImplementation::ReportInterfaceStateChange(const Exchange::INetworkManager::InterfaceState state, const string interface) { LOG_ENTRY_FUNCTION(); @@ -730,17 +898,17 @@ namespace WPEFramework m_wlanEnabled.store(true); } - _notificationLock.Lock(); - NMLOG_INFO("Posting onInterfaceChange %s - %u", interface.c_str(), (unsigned)state); - for (const auto callback : _notificationCallbacks) { - callback->onInterfaceStateChange(state, interface); + { + InterfaceStateChangeData eventData{state, interface}; + NMLOG_INFO("Posting onInterfaceChange %s - %u", interface.c_str(), (unsigned)state); + enqueueEvent(NM_ON_INTERFACESTATE_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); + return; } void NetworkManagerImplementation::ReportActiveInterfaceChange(const string prevActiveInterface, const string currentActiveinterface) { - NMLOG_INFO("Posting onActiveInterfaceChange %s", currentActiveinterface.c_str()); + LOG_ENTRY_FUNCTION(); if(currentActiveinterface == "eth0") { @@ -753,13 +921,11 @@ namespace WPEFramework m_wlanEnabled.store(true); } - // FIXME : This could be the place to define `m_defaultInterface` to incoming `currentActiveinterface`. - // m_defaultInterface = currentActiveinterface; - _notificationLock.Lock(); - for (const auto callback : _notificationCallbacks) { - callback->onActiveInterfaceChange(prevActiveInterface, currentActiveinterface); + { + ActiveInterfaceChangeData eventData{prevActiveInterface, currentActiveinterface}; + NMLOG_INFO("Posting onActiveInterfaceChange %s", currentActiveinterface.c_str()); + enqueueEvent(NM_ON_ACTIVEINTERFACE_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); #if USE_TELEMETRY NMLOG_INFO("NM_INTERFACE_STATUS = Interface changed to %s", currentActiveinterface.c_str()); logTelemetry("NM_INTERFACE_STATUS", "Interface changed to " + currentActiveinterface); @@ -799,19 +965,17 @@ namespace WPEFramework NMLOG_DEBUG("No need to trigger connectivity monitor interface is %s", interface.c_str()); } - _notificationLock.Lock(); - NMLOG_INFO("Posting onIPAddressChange %s: %s %s %s", - (Exchange::INetworkManager::IP_ACQUIRED == status) ? "IP acquired" : "IP lost", - interface.c_str(), ipversion.c_str(), ipaddress.c_str()); - for (const auto callback : _notificationCallbacks) { - callback->onIPAddressChange(interface, ipversion, ipaddress, status); + { + IPAddressChangeData eventData{interface, ipversion, ipaddress, status}; + NMLOG_INFO("Posting onIPAddressChange %s: %s %s %s", (Exchange::INetworkManager::IP_ACQUIRED == status) ? "IP acquired" : "IP lost", + interface.c_str(), ipversion.c_str(), ipaddress.c_str()); + enqueueEvent(NM_ON_IPADDRESS_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); } void NetworkManagerImplementation::ReportInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState, const string interface) { - NMLOG_INFO("Posting onInternetStatusChange with current state as %u", (unsigned)currState); + LOG_ENTRY_FUNCTION(); #if USE_TELEMETRY // Log error only when ethernet is up and there's no internet if(currState == Exchange::INetworkManager::INTERNET_NOT_AVAILABLE && @@ -823,11 +987,12 @@ namespace WPEFramework logTelemetry("NM_ETHERNET_CONNECTIVITY", "Ethernet connectivity failed"); } #endif - _notificationLock.Lock(); - for (const auto callback : _notificationCallbacks) { - callback->onInternetStatusChange(prevState, currState, interface); + { + InternetStatusChangeData eventData{prevState, currState, interface}; + NMLOG_INFO("Posting onInternetStatusChange with current state as %u", (unsigned)currState); + enqueueEvent(NM_ON_INTERNETSTATUS_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); + #if USE_TELEMETRY string stateStr = Core::EnumerateType(currState).Data(); NMLOG_INFO("NM_INTERNET_STATUS = %s", stateStr.c_str()); @@ -837,6 +1002,7 @@ namespace WPEFramework int32_t NetworkManagerImplementation::logSSIDs(Logging level, const JsonArray &ssids) { + LOG_ENTRY_FUNCTION(); Logging inLevel; GetLogLevel(inLevel); if (level > inLevel) @@ -856,6 +1022,7 @@ namespace WPEFramework void NetworkManagerImplementation::ReportAvailableSSIDs(const JsonArray &arrayofWiFiScanResults) { + LOG_ENTRY_FUNCTION(); string jsonOfWiFiScanResults; string jsonOfFilterScanResults; JsonArray filterResult = arrayofWiFiScanResults; @@ -880,15 +1047,15 @@ namespace WPEFramework NMLOG_INFO("Posting onAvailableSSIDs event with %d SSIDs as,", filterResult.Length()); logSSIDs(LOG_LEVEL_INFO, filterResult); - _notificationLock.Lock(); - for (const auto callback : _notificationCallbacks) { - callback->onAvailableSSIDs(jsonOfFilterScanResults); + { + AvailableSSIDsData eventData{jsonOfFilterScanResults}; + enqueueEvent(NM_ON_AVAILABLESSIDS, std::move(eventData)); } - _notificationLock.Unlock(); } void NetworkManagerImplementation::startWiFiSignalQualityMonitor(int interval) { + LOG_ENTRY_FUNCTION(); if (m_isRunning.load()) { NMLOG_INFO("WiFiSignalQualityMonitor Thread is already running."); return; @@ -904,6 +1071,7 @@ namespace WPEFramework void NetworkManagerImplementation::stopWiFiSignalQualityMonitor() { + LOG_ENTRY_FUNCTION(); if (!m_isRunning.load()) return; // No thread to stop @@ -1088,6 +1256,7 @@ namespace WPEFramework void NetworkManagerImplementation::processMonitor(uint16_t interval) { + LOG_ENTRY_FUNCTION(); pid_t pid = getpid(); string path = "/proc/"; @@ -1139,6 +1308,7 @@ namespace WPEFramework void NetworkManagerImplementation::monitorThreadFunction(int interval) { + LOG_ENTRY_FUNCTION(); static Exchange::INetworkManager::WiFiSignalQuality oldSignalQuality = Exchange::INetworkManager::WIFI_SIGNAL_DISCONNECTED; NMLOG_INFO("WiFiSignalQualityMonitor thread started ! (%d)", interval); while (true) @@ -1177,6 +1347,7 @@ namespace WPEFramework void NetworkManagerImplementation::ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state) { + LOG_ENTRY_FUNCTION(); /* start signal strength monitor when wifi connected */ if(INetworkManager::WiFiState::WIFI_STATE_CONNECTED == state) { @@ -1195,25 +1366,25 @@ namespace WPEFramework NMLOG_INFO("NM_WIFI_STATUS = %s", stateStr.c_str()); logTelemetry("NM_WIFI_STATUS", stateStr); #endif - _notificationLock.Lock(); - for (const auto callback : _notificationCallbacks) { - callback->onWiFiStateChange(state); + { + WiFiStateChangeData eventData{state}; + enqueueEvent(NM_ON_WIFISTATE_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); } void NetworkManagerImplementation::ReportWiFiSignalQualityChange(const string ssid, const int strength, const int noise, const int snr, const Exchange::INetworkManager::WiFiSignalQuality quality) { - _notificationLock.Lock(); - NMLOG_INFO("Posting onWiFiSignalQualityChange %d", strength); - for (const auto callback : _notificationCallbacks) { - callback->onWiFiSignalQualityChange(ssid, strength, noise, snr, quality); + LOG_ENTRY_FUNCTION(); + { + WiFiSignalQualityChangeData eventData{ssid, strength, noise, snr, quality}; + NMLOG_INFO("Posting onWiFiSignalQualityChange %d", strength); + enqueueEvent(NM_ON_WIFISIGNALQUALITY_CHANGE, std::move(eventData)); } - _notificationLock.Unlock(); } void NetworkManagerImplementation::logTelemetry(const std::string& eventName, const std::string& message) { + LOG_ENTRY_FUNCTION(); #if USE_TELEMETRY T2ERROR t2error = t2_event_s(eventName.c_str(), const_cast(message.c_str())); if (t2error != T2ERROR_SUCCESS) { @@ -1228,6 +1399,7 @@ namespace WPEFramework const Exchange::IPowerManager::PowerState newState, std::function sendAck) { + LOG_ENTRY_FUNCTION(); // Called from NetworkManagerPowerClient's power thread. NMLOG_DEBUG("OnPowerModePreChange: current=%d new=%d", static_cast(currentState), static_cast(newState)); @@ -1310,6 +1482,7 @@ namespace WPEFramework const Exchange::IPowerManager::PowerState currentState, const Exchange::IPowerManager::PowerState newState) { + LOG_ENTRY_FUNCTION(); NMLOG_INFO("OnPowerModeChanged: current=%d new=%d", static_cast(currentState), static_cast(newState)); if (currentState == Exchange::IPowerManager::PowerState::POWER_STATE_STANDBY_DEEP_SLEEP) { @@ -1441,6 +1614,7 @@ namespace WPEFramework Exchange::INetworkManager::IPAddress IpFamilyCache::toIPAddress() const { + LOG_ENTRY_FUNCTION(); Exchange::INetworkManager::IPAddress addr{}; /* Detect IP version from any available address. */ bool isIPv6 = false; diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h index b7bffe91..bafe337f 100644 --- a/plugin/NetworkManagerImplementation.h +++ b/plugin/NetworkManagerImplementation.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include using namespace std; @@ -209,20 +211,70 @@ namespace WPEFramework Core::JSON::DecUInt32 loglevel; }; + enum NMPublishEvents { + NM_ON_INTERFACESTATE_CHANGE = 0, + NM_ON_ACTIVEINTERFACE_CHANGE, + NM_ON_IPADDRESS_CHANGE, + NM_ON_INTERNETSTATUS_CHANGE, + NM_ON_AVAILABLESSIDS, + NM_ON_WIFISTATE_CHANGE, + NM_ON_WIFISIGNALQUALITY_CHANGE + }; - class Job : public Core::IDispatch { - public: - Job(function work) - : _work(work) - { - } - void Dispatch() override - { - _work(); - } + // Typed event data structures + struct InterfaceStateChangeData { + Exchange::INetworkManager::InterfaceState state; + string interface; + }; - private: - function _work; + struct ActiveInterfaceChangeData { + string prevActiveInterface; + string currentActiveInterface; + }; + + struct IPAddressChangeData { + string interface; + string ipversion; + string ipaddress; + Exchange::INetworkManager::IPStatus status; + }; + + struct InternetStatusChangeData { + Exchange::INetworkManager::InternetStatus prevState; + Exchange::INetworkManager::InternetStatus currState; + string interface; + }; + + struct AvailableSSIDsData { + string jsonResult; // Pre-serialized JSON string + }; + + struct WiFiStateChangeData { + Exchange::INetworkManager::WiFiState state; + }; + + struct WiFiSignalQualityChangeData { + string ssid; + int strength; + int noise; + int snr; + Exchange::INetworkManager::WiFiSignalQuality quality; + }; + + using EventDataVariant = std::variant< + std::monostate, + InterfaceStateChangeData, + ActiveInterfaceChangeData, + IPAddressChangeData, + InternetStatusChangeData, + AvailableSSIDsData, + WiFiStateChangeData, + WiFiSignalQualityChangeData + >; + + struct EventData { + NMPublishEvents event; + EventDataVariant data; }; public: @@ -344,6 +396,9 @@ namespace WPEFramework void monitorThreadFunction(int interval); int32_t logSSIDs(Logging level, const JsonArray &ssids); void processMonitor(uint16_t interval); + void eventThreadFunction(); + void enqueueEvent(NMPublishEvents event, EventDataVariant&& data); + void dispatchEvent(NMPublishEvents event, const EventDataVariant& data); private: std::list _notificationCallbacks; @@ -365,6 +420,12 @@ namespace WPEFramework std::atomic m_processMonThreadStop{false}; std::condition_variable m_processMonCondVar; + std::thread m_eventThread; + std::queue m_eventQueue; + std::mutex m_eventMutex; + std::condition_variable m_eventCondVar; + std::atomic m_eventThreadStop{false}; + std::atomic m_isRunning{false}; std::atomic m_stopThread{false}; std::mutex m_condVariableMutex; diff --git a/tests/l1Test/CMakeLists.txt b/tests/l1Test/CMakeLists.txt index dfae9937..ec7b8c37 100644 --- a/tests/l1Test/CMakeLists.txt +++ b/tests/l1Test/CMakeLists.txt @@ -44,7 +44,7 @@ if(ENABLE_ROUTER_DISCOVERY_TOOL) ) set_target_properties(${NM_ROUTER_DISCOVERY_L1_TEST} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) @@ -78,7 +78,7 @@ target_link_libraries(${NM_CLASS_L1_TEST} PRIVATE ) set_target_properties(${NM_CLASS_L1_TEST} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) diff --git a/tests/l2Test/legacy/CMakeLists.txt b/tests/l2Test/legacy/CMakeLists.txt index 5106f18e..ae168861 100644 --- a/tests/l2Test/legacy/CMakeLists.txt +++ b/tests/l2Test/legacy/CMakeLists.txt @@ -40,11 +40,11 @@ add_executable(${NM_LEGACY_NETWORK_UT} ) set_target_properties(${NM_LEGACY_WIFI_UT} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) set_target_properties(${NM_LEGACY_NETWORK_UT} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) diff --git a/tests/l2Test/libnm/CMakeLists.txt b/tests/l2Test/libnm/CMakeLists.txt index 9b1a44d0..17be8eea 100644 --- a/tests/l2Test/libnm/CMakeLists.txt +++ b/tests/l2Test/libnm/CMakeLists.txt @@ -49,7 +49,7 @@ add_executable(${NM_LIBNM_PROXY_L2_TEST} ) set_target_properties(${NM_LIBNM_PROXY_L2_TEST} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) diff --git a/tests/l2Test/rdk/CMakeLists.txt b/tests/l2Test/rdk/CMakeLists.txt index 3a94c63d..cc5ecc59 100644 --- a/tests/l2Test/rdk/CMakeLists.txt +++ b/tests/l2Test/rdk/CMakeLists.txt @@ -44,7 +44,7 @@ add_executable(${NM_RDK_PROXY_L2_TEST} ) set_target_properties(${NM_RDK_PROXY_L2_TEST} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) diff --git a/tools/plugincli/CMakeLists.txt b/tools/plugincli/CMakeLists.txt index 56883676..6784ff84 100644 --- a/tools/plugincli/CMakeLists.txt +++ b/tools/plugincli/CMakeLists.txt @@ -74,7 +74,7 @@ if(ENABLE_GNOME_GDBUS) ) set_target_properties(${PLUGIN_GDBUS_CLI} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES ) @@ -106,7 +106,7 @@ else() ) set_target_properties(${PLUGIN_LIBNM_CLI} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES )