From 73b14f68132bf5936a33211dc4061936a58f242f Mon Sep 17 00:00:00 2001 From: cmuhammedrafi Date: Fri, 27 Dec 2024 06:22:04 +0000 Subject: [PATCH] test code --- NetworkManagerConnectivity.cpp | 275 ++++++++++++++++++--------------- NetworkManagerConnectivity.h | 38 +++-- 2 files changed, 171 insertions(+), 142 deletions(-) diff --git a/NetworkManagerConnectivity.cpp b/NetworkManagerConnectivity.cpp index 27143f2..1bd9f6b 100644 --- a/NetworkManagerConnectivity.cpp +++ b/NetworkManagerConnectivity.cpp @@ -49,6 +49,100 @@ namespace WPEFramework } } + void EndpointManager::writeEndpointsToFile(const std::vector& endpoints) + { + std::ofstream outputFile(m_CachefilePath); + if (outputFile.is_open()) + { + for (const std::string& str : endpoints) + { + outputFile << str << '\n'; + } + outputFile.close(); + } + else + { + NMLOG_ERROR("Connectivity endpoints file write error"); + } + } + + std::vector EndpointManager::readEndpointsFromFile() + { + std::vector readStrings; + std::ifstream inputFile(m_CachefilePath); + if (inputFile.is_open()) + { + std::string line; + while (std::getline(inputFile, line)) + { + readStrings.push_back(line); + } + inputFile.close(); + } + else + { + NMLOG_ERROR("Failed to open connectivity endpoint cache file"); + } + return readStrings; + } + + void EndpointManager::setConnectivityMonitorEndpoints(const std::vector& endpoints) + { + const std::lock_guard lock(m_endpointMutex); + if(endpoints.empty()) + { + NMLOG_ERROR("Empty endpoints"); + return; + } + + m_Endpoints.clear(); + for (auto endpoint : endpoints) { + if(!endpoint.empty() && endpoint.size() > 3) + m_Endpoints.push_back(endpoint.c_str()); + else + NMLOG_ERROR("endpoint not vallied = %s", endpoint.c_str()); + } + + // write the endpoints to a file + writeEndpointsToFile(m_Endpoints); + + std::string endpointsStr; + for (const auto& endpoint : m_Endpoints) + endpointsStr.append(endpoint).append(" "); + NMLOG_INFO("Connectivity monitor endpoints updated -: %d :- %s", static_cast(m_Endpoints.size()), endpointsStr.c_str()); + } + + EndpointManager::EndpointManager() + { + m_CachefilePath = NMCONNECTIVITY_MONITOR_CACHE_FILE; + m_Endpoints = {NMCONNECTIVITY_MONITOR_DEFAULT_ENDPOINT}; + + std::ifstream inputFile(m_CachefilePath); + if (inputFile.is_open()) + { + std::string line; + std::vector endpoints{}; + while (std::getline(inputFile, line)) + { + if(!line.empty() && line.size() > 3) + endpoints.push_back(line); + } + NMLOG_WARNING("cached connectivity endpoints loaded .."); + setConnectivityMonitorEndpoints(endpoints); + inputFile.close(); + } + else + { + NMLOG_ERROR("no endpoint cache file found"); + } + } + + std::vector EndpointManager::getConnectivityMonitorEndpoints() + { + const std::lock_guard lock(m_endpointMutex); + return m_Endpoints; + } + bool DnsResolver::resolveIP(std::string& uri, nsm_ipversion ipversion) { struct addrinfo sockAddrProps, *resultAddr= NULL; @@ -123,49 +217,6 @@ namespace WPEFramework resolveIP(m_domain, ipversion); } - bool EndpointCache::isEndpointCashFileExist() - { - std::ifstream fileStream(CachefilePath); - return fileStream.is_open(); - } - - void EndpointCache::writeEnpointsToFile(const std::vector& endpoints) - { - std::ofstream outputFile(CachefilePath); - if (outputFile.is_open()) - { - for (const std::string& str : endpoints) - { - outputFile << str << '\n'; - } - outputFile.close(); - } - else - { - NMLOG_ERROR("Connectivity endpoints file write error"); - } - } - - std::vector EndpointCache::readEnpointsFromFile() - { - std::vector readStrings; - std::ifstream inputFile(CachefilePath); - if (inputFile.is_open()) - { - std::string line; - while (std::getline(inputFile, line)) - { - readStrings.push_back(line); - } - inputFile.close(); - } - else - { - NMLOG_ERROR("Failed to open connectivity endpoint cache file"); - } - return readStrings; - } - TestConnectivity::TestConnectivity(const std::vector& endpoints, long timeout_ms, bool headReq, nsm_ipversion ipversion) { internetSate = UNKNOWN; @@ -390,16 +441,9 @@ namespace WPEFramework } ConnectivityMonitor::ConnectivityMonitor() - :connectivityMonitorEndpt({"http://clients3.google.com/generate_204"}) { - if(endpointCache.isEndpointCashFileExist()) - { - std::vector cachedEndPnt = endpointCache.readEnpointsFromFile(); - setConnectivityMonitorEndpoints(cachedEndPnt); - NMLOG_WARNING("cached connectivity endpoints loaded .."); - } - m_cmRunning = false; + m_notify = true; m_InternetState = nsm_internetState::UNKNOWN; m_Ipv4InternetState = nsm_internetState::UNKNOWN; m_Ipv6InternetState = nsm_internetState::UNKNOWN; @@ -414,32 +458,12 @@ namespace WPEFramework std::vector ConnectivityMonitor::getConnectivityMonitorEndpoints() { - const std::lock_guard lock(endpointMutex); - std::vector endpoints; - for (auto endpoint : connectivityMonitorEndpt) { - endpoints.push_back(endpoint); - } - return endpoints; + return m_endpoint.getConnectivityMonitorEndpoints(); } void ConnectivityMonitor::setConnectivityMonitorEndpoints(const std::vector &endpoints) { - const std::lock_guard lock(endpointMutex); - connectivityMonitorEndpt.clear(); - for (auto endpoint : endpoints) { - if(!endpoint.empty() && endpoint.size() > 3) - connectivityMonitorEndpt.push_back(endpoint.c_str()); - else - NMLOG_ERROR("endpoint not vallied = %s", endpoint.c_str()); - } - - // write the endpoints to a file - endpointCache.writeEnpointsToFile(connectivityMonitorEndpt); - - std::string endpointsStr; - for (const auto& endpoint : connectivityMonitorEndpt) - endpointsStr.append(endpoint).append(" "); - NMLOG_INFO("Connectivity monitor endpoints -: %d :- %s", static_cast(connectivityMonitorEndpt.size()), endpointsStr.c_str()); + m_endpoint.setConnectivityMonitorEndpoints(endpoints); } bool ConnectivityMonitor::isConnectedToInternet(nsm_ipversion ipversion) @@ -480,8 +504,8 @@ namespace WPEFramework { if(m_Ipv4InternetState == nsm_internetState::CAPTIVE_PORTAL || m_Ipv6InternetState == nsm_internetState::CAPTIVE_PORTAL) { - NMLOG_INFO("captive portal URI = %s", captiveURL.c_str()); - return captiveURL; + NMLOG_INFO("captive portal URI = %s", m_captiveURI.c_str()); + return m_captiveURI; } NMLOG_WARNING("No captive portal found !"); @@ -517,21 +541,21 @@ namespace WPEFramework return true; } - bool ConnectivityMonitor::switchToInitialCheck() - { + bool ConnectivityMonitor::switchToInitialCheck() + { m_switchToInitial = true; - notify = true; // notify internet state becuse some network state change may happen + m_notify = true; // m_notify internet state because some network state change may happen m_cmCv.notify_one(); NMLOG_INFO("switching to initial check"); return true; - } + } void ConnectivityMonitor::notifyInternetStatusChangedEvent(nsm_internetState newInternetState) { static Exchange::INetworkManager::InternetStatus oldState = Exchange::INetworkManager::InternetStatus::INTERNET_UNKNOWN; if(_instance != nullptr) { - NMLOG_INFO("notify internet state %s", getInternetStateString(newInternetState)); + NMLOG_INFO("m_notify internet state %s", getInternetStateString(newInternetState)); Exchange::INetworkManager::InternetStatus newState = static_cast(newInternetState); _instance->ReportInternetStatusChange(oldState , newState); m_InternetState = newInternetState; @@ -545,15 +569,14 @@ namespace WPEFramework { int timeoutInSec = NMCONNECTIVITY_MONITOR_MIN_INTERVAL; nsm_ipversion ipVersion = NSM_IPRESOLVE_WHATEVER; - nsm_internetState currentInternetState = UNKNOWN; + nsm_internetState currentInternetState = NO_INTERNET; int InitialRetryCount = 0; int IdealRetryCount = 0; - bool doDnsResolve = false; - - m_InternetState = UNKNOWN; + m_switchToInitial = true; + m_InternetState = NO_INTERNET; m_Ipv4InternetState = UNKNOWN; m_Ipv6InternetState = UNKNOWN; - notify = true; + m_notify = true; while (m_cmRunning) { // Check if no interfaces are connected @@ -564,7 +587,7 @@ namespace WPEFramework m_Ipv4InternetState = NO_INTERNET; m_Ipv6InternetState = NO_INTERNET; if (InitialRetryCount == 0) - notify = true; + m_notify = true; InitialRetryCount = 1; } // Initial case monitoring @@ -574,19 +597,19 @@ namespace WPEFramework // Lambda functions to check connectivity for IPv4 and IPv6 auto curlCheckThrdIpv4 = [&]() { - TestConnectivity testInternet(getConnectivityMonitorEndpoints(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, + TestConnectivity testInternet(m_endpoint(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, NMCONNECTIVITY_CURL_HEAD_REQUEST, NSM_IPRESOLVE_V4); m_Ipv4InternetState = testInternet.getInternetState(); if(m_Ipv6InternetState == CAPTIVE_PORTAL) - captiveURL = testInternet.getCaptivePortal(); + m_captiveURI = testInternet.getCaptivePortal(); }; auto curlCheckThrdIpv6 = [&]() { - TestConnectivity testInternet(getConnectivityMonitorEndpoints(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, + TestConnectivity testInternet(m_endpoint(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, NMCONNECTIVITY_CURL_HEAD_REQUEST, NSM_IPRESOLVE_V6); m_Ipv6InternetState = testInternet.getInternetState(); if(m_Ipv6InternetState == CAPTIVE_PORTAL) - captiveURL = testInternet.getCaptivePortal(); + m_captiveURI = testInternet.getCaptivePortal(); }; // Start threads for IPv4 and IPv6 checks @@ -601,7 +624,7 @@ namespace WPEFramework if (m_Ipv4InternetState == NO_INTERNET && m_Ipv6InternetState == NO_INTERNET) { currentInternetState = NO_INTERNET; if (InitialRetryCount == 0) - notify = true; + m_notify = true; InitialRetryCount = 1; // continue same check for 5 sec } else { if (m_Ipv4InternetState == FULLY_CONNECTED || m_Ipv6InternetState == FULLY_CONNECTED) { @@ -619,7 +642,7 @@ namespace WPEFramework } if (InitialRetryCount == 0) - notify = true; + m_notify = true; if (currentInternetState != m_InternetState) { NMLOG_DEBUG("connectivity monitor state change %s", getInternetStateString(m_InternetState)); @@ -631,53 +654,55 @@ namespace WPEFramework if (InitialRetryCount > NM_CONNECTIVITY_MONITOR_RETRY_COUNT) { m_switchToInitial = false; - notify = true; + m_notify = true; InitialRetryCount = 0; IdealRetryCount = 0; } } // Ideal case monitoring else { - NMLOG_DEBUG("ideal connection check ..."); + timeoutInSec = NMCONNECTIVITY_MONITOR_RETRY_INTERVAL; InitialRetryCount = 0; - if (doDnsResolve) { - DnsResolver dnsResolver(getConnectivityMonitorEndpoints()[0], ipVersion); // only first endpoint with specific ipversion - if (dnsResolver()) { - NMLOG_INFO("DNS resolved, success !!!"); - IdealRetryCount = 0; - currentInternetState = FULLY_CONNECTED; - } else { - currentInternetState = NO_INTERNET; - } - doDnsResolve = false; - } else { - TestConnectivity testInternet(getConnectivityMonitorEndpoints(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, - NMCONNECTIVITY_CURL_HEAD_REQUEST, ipVersion); - currentInternetState = testInternet.getInternetState(); - } + TestConnectivity testInternet(m_endpoint(), NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS, + NMCONNECTIVITY_CURL_HEAD_REQUEST, ipVersion); + currentInternetState = testInternet.getInternetState(); + + if (currentInternetState == CAPTIVE_PORTAL) // if captive portal found copy the URL + m_captiveURI = testInternet.getCaptivePortal(); if (currentInternetState != m_InternetState) { if (currentInternetState == NO_INTERNET && m_InternetState == FULLY_CONNECTED) { - timeoutInSec = NMCONNECTIVITY_MONITOR_MIN_INTERVAL; // retry in 5 sec - IdealRetryCount++; - if (IdealRetryCount > NM_CONNECTIVITY_MONITOR_RETRY_COUNT) { + DnsResolver dnsResolver(getConnectivityMonitorEndpoints()[0], ipVersion); // only first endpoint with specific ipversion + if (dnsResolver()) { + NMLOG_INFO("DNS resolved, success !!!"); IdealRetryCount = 0; - m_InternetState = NO_INTERNET; - m_Ipv4InternetState = NO_INTERNET; - m_Ipv6InternetState = NO_INTERNET; // reset all states to NO_INTERNET - notify = true; - m_switchToInitial = true; // switch to initial check after 3 retries - InitialRetryCount = 1; // reset initial retry count it will not post the event - NMLOG_DEBUG("No internet retrying completed notifying !!!"); - } else { - NMLOG_INFO("No internet retrying connection check %d ...", IdealRetryCount); - doDnsResolve = true; // do dns resolve for the next check + currentInternetState = FULLY_CONNECTED; + } + else + { + NMLOG_WARNING("DNS resolve failed !!!"); + timeoutInSec = NMCONNECTIVITY_MONITOR_MIN_INTERVAL; // retry in 5 sec + IdealRetryCount++; + if (IdealRetryCount >= NM_CONNECTIVITY_MONITOR_RETRY_COUNT) { + IdealRetryCount = 0; + m_InternetState = NO_INTERNET; + m_Ipv4InternetState = NO_INTERNET; + m_Ipv6InternetState = NO_INTERNET; // reset all states to NO_INTERNET + m_switchToInitial = true; // switch to initial check after 3 retries + InitialRetryCount = 1; // reset initial retry count it will not post the event + m_notify = true; + NMLOG_DEBUG("No internet retrying completed notifying !!!"); + } else { + NMLOG_INFO("No internet retrying connection check %d ...", IdealRetryCount); + } } - } else { // a state change happened but it is not fully connected to no internet + } else { + // a state change happened but it is not fully connected to no internet + // switch to initial check to get the correct state m_switchToInitial = true; InitialRetryCount = 0; IdealRetryCount = 0; @@ -694,10 +719,10 @@ namespace WPEFramework } } - if (notify) { + if (m_notify) { m_InternetState = currentInternetState; notifyInternetStatusChangedEvent(m_InternetState); - notify = false; + m_notify = false; } if (!m_cmRunning) diff --git a/NetworkManagerConnectivity.h b/NetworkManagerConnectivity.h index 153e249..1340703 100644 --- a/NetworkManagerConnectivity.h +++ b/NetworkManagerConnectivity.h @@ -58,7 +58,8 @@ enum nsm_connectivity_httpcode { #define NMCONNECTIVITY_CURL_HEAD_REQUEST true #define NMCONNECTIVITY_CURL_GET_REQUEST false - +#define NMCONNECTIVITY_MONITOR_CACHE_FILE "/tmp/nm.plugin.endpoints" +#define NMCONNECTIVITY_MONITOR_DEFAULT_ENDPOINT "http://clients3.google.com/generate_204" #define NMCONNECTIVITY_MONITOR_MIN_INTERVAL 5 // sec #define NMCONNECTIVITY_MONITOR_RETRY_INTERVAL 30 // sec #define NMCONNECTIVITY_CURL_REQUEST_TIMEOUT_MS 5000 // ms @@ -86,18 +87,22 @@ namespace WPEFramework /* * Save user specific endpoint into a cache file and load from the file - * if monitorEndpoints are empty in case WPEFramework is restarted. + * if endpoints are empty in case plugin is restarted. */ - class EndpointCache { - public: - bool isEndpointCashFileExist(); - void writeEnpointsToFile(const std::vector& endpoints); - std::vector readEnpointsFromFile(); + class EndpointManager { + public: + EndpointManager(); + ~EndpointManager() {} + void writeEndpointsToFile(const std::vector& endpoints); + std::vector readEndpointsFromFile(); + void setConnectivityMonitorEndpoints(const std::vector& endpoints); + std::vector getConnectivityMonitorEndpoints(); + std::vector operator()() { return getConnectivityMonitorEndpoints(); } - EndpointCache() : CachefilePath("/tmp/nm.plugin.endpoints") {} - ~EndpointCache(){} - private: - std::string CachefilePath; + private: + std::string m_CachefilePath; + std::vector m_Endpoints; + std::mutex m_endpointMutex; }; class TestConnectivity @@ -108,7 +113,7 @@ namespace WPEFramework public: TestConnectivity(const std::vector& endpoints, long timeout_ms = 2000, bool = true, nsm_ipversion ipversion = NSM_IPRESOLVE_WHATEVER); ~TestConnectivity(){} - std::string& getCaptivePortal() {return captivePortalURI;} + std::string getCaptivePortal() {return captivePortalURI;} nsm_internetState getInternetState(){return internetSate;} private: nsm_internetState checkCurlResponse(const std::vector& endpoints, long timeout_ms, bool headReq, nsm_ipversion ipversion); @@ -141,15 +146,14 @@ namespace WPEFramework std::atomic m_cmRunning; std::condition_variable m_cmCv; std::mutex m_cmMutex; - std::atomic notify; + std::atomic m_notify; std::atomic m_switchToInitial; - std::vector connectivityMonitorEndpt; - std::string captiveURL; - EndpointCache endpointCache; - std::mutex endpointMutex; + std::string m_captiveURI; std::atomic m_InternetState; std::atomic m_Ipv4InternetState; std::atomic m_Ipv6InternetState; + /* manages endpoints */ + EndpointManager m_endpoint; }; } // namespace Plugin } // namespace WPEFramework