diff --git a/NetworkManager.cpp b/NetworkManager.cpp index c7d57b87..baa8d482 100644 --- a/NetworkManager.cpp +++ b/NetworkManager.cpp @@ -44,7 +44,7 @@ namespace WPEFramework _notification(this) { // Don't do any work in the constructor - all set up should be done in Initialize - m_defaultInterface = "wlan0"; + m_primaryInterfaceCache = "wlan0"; } NetworkManager::~NetworkManager() diff --git a/NetworkManager.h b/NetworkManager.h index ce4771cf..1838c545 100644 --- a/NetworkManager.h +++ b/NetworkManager.h @@ -28,6 +28,7 @@ #include #include +#include namespace WPEFramework { @@ -123,7 +124,12 @@ namespace WPEFramework JsonObject params; params["interface"] = interface; params["state"] = InterfaceStateToString(event); + if(interface == "wlan0") + _parent.m_wifiStateCache.reset(); _parent.Notify("onInterfaceStateChange", params); + _parent.m_primaryInterfaceCache.reset(); + _parent.m_ipv6AddressCache.reset(); + _parent.m_ipv4AddressCache.reset(); } void onIPAddressChange(const string interface, const bool isAcquired, const bool isIPv6, const string ipAddress) override @@ -134,6 +140,10 @@ namespace WPEFramework params["interface"] = interface; params["ipAddress"] = ipAddress; params["isIPv6"] = isIPv6; + if(isIPv6) + _parent.m_ipv6AddressCache.reset(); + else + _parent.m_ipv4AddressCache.reset(); _parent.Notify("onIPAddressChange", params); } @@ -144,7 +154,7 @@ namespace WPEFramework params["oldInterfaceName"] = prevActiveInterface; params["newInterfaceName"] = currentActiveinterface; _parent.Notify("onActiveInterfaceChange", params); - + _parent.m_primaryInterfaceCache.reset(); } void onInternetStatusChange(const Exchange::INetworkManager::InternetStatus oldState, const Exchange::INetworkManager::InternetStatus newstate) override @@ -184,6 +194,7 @@ namespace WPEFramework JsonObject result; result["state"] = static_cast (state); _parent.Notify("onWiFiStateChange", result); + _parent.m_wifiStateCache = state; } void onWiFiSignalStrengthChange(const string ssid, const string signalLevel, const Exchange::INetworkManager::WiFiSignalQuality signalQuality) override @@ -264,7 +275,55 @@ namespace WPEFramework return (m_publicIPAddress.empty() == true ? PluginHost::ISubSystem::IInternet::UNKNOWN : (m_publicIPAddressType == "IPV6" ? PluginHost::ISubSystem::IInternet::IPV6 : PluginHost::ISubSystem::IInternet::IPV4)); } void PublishToThunderAboutInternet(); + /* Class to store and manage cached data */ + template + class Cache { + public: + Cache() : is_set(false) {} + + Cache& operator=(const CacheValue& value) { + std::lock_guard lock(mutex); + this->value = value; + is_set.store(true); + return *this; + } + + Cache& operator=(CacheValue&& value) { + std::lock_guard lock(mutex); + this->value = std::move(value); + is_set.store(true); + return *this; + } + + bool isSet() const { + return is_set.load(); + } + + void reset() { + is_set.store(false); + } + + const CacheValue& getValue() const { + std::lock_guard lock(mutex); + return value; + } + + CacheValue& getValue() { + std::lock_guard lock(mutex); + return value; + } + + private: + CacheValue value; + std::atomic is_set; + mutable std::mutex mutex; + }; + // cached varibales + Cache m_wifiStateCache; + Cache m_ipv4AddressCache; + Cache m_ipv6AddressCache; + Cache m_primaryInterfaceCache; private: // Notification/event handlers // Clean up when we're told to deactivate @@ -315,7 +374,6 @@ namespace WPEFramework Exchange::INetworkManager *_networkManager; Core::Sink _notification; string m_publicIPAddress; - string m_defaultInterface; string m_publicIPAddressType; }; } diff --git a/NetworkManagerJsonRpc.cpp b/NetworkManagerJsonRpc.cpp index a99978e6..06da7b6f 100644 --- a/NetworkManagerJsonRpc.cpp +++ b/NetworkManagerJsonRpc.cpp @@ -179,7 +179,13 @@ namespace WPEFramework LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; string interface; - if (_networkManager) + if(m_primaryInterfaceCache.isSet()) + { + NMLOG_INFO("reading interface cached values"); + interface = m_primaryInterfaceCache.getValue(); + rc = Core::ERROR_NONE; + } + else if (_networkManager) rc = _networkManager->GetPrimaryInterface(interface); else rc = Core::ERROR_UNAVAILABLE; @@ -187,7 +193,7 @@ namespace WPEFramework if (Core::ERROR_NONE == rc) { response["interface"] = interface; - m_defaultInterface = interface; + m_primaryInterfaceCache = interface; response["success"] = true; } LOG_OUTPARAM(); @@ -278,6 +284,7 @@ namespace WPEFramework uint32_t rc = Core::ERROR_GENERAL; string interface = ""; string ipversion = ""; + bool isCacheLoaded = false; Exchange::INetworkManager::IPAddressInfo result{}; if (parameters.HasLabel("interface")) @@ -285,16 +292,56 @@ namespace WPEFramework if (parameters.HasLabel("ipversion")) ipversion = parameters["ipversion"].String(); - if (!interface.empty() && ("wlan0" != interface) && ("eth0" != interface)) + if (interface.empty() || ("wlan0" != interface && "eth0" != interface)) { - rc = Core::ERROR_BAD_REQUEST; - return rc; + if(!interface.empty()) { + NMLOG_WARNING("interface is neither wlan0 nor eth0: %s", interface.c_str()); + return Core::ERROR_BAD_REQUEST; + } + + interface = m_primaryInterfaceCache.getValue(); } - if (_networkManager) - rc = _networkManager->GetIPSettings(interface, ipversion, result); - else - rc = Core::ERROR_UNAVAILABLE; + if(m_primaryInterfaceCache.isSet() && (interface == m_primaryInterfaceCache.getValue())) + { + /* If ipversion is empty, IPv4 will be taken as the default version */ + if(m_ipv4AddressCache.isSet() && (ipversion.empty() || strcasecmp(ipversion.c_str(), "IPv4") == 0)) + { + NMLOG_INFO("reading ipv4 settings cached values"); + result = m_ipv4AddressCache.getValue(); + rc = Core::ERROR_NONE; + isCacheLoaded = true; + } + else if(m_ipv6AddressCache.isSet() && (ipversion.empty() || strcasecmp(ipversion.c_str(), "IPv6") == 0)) + { + NMLOG_INFO("reading ipv6 settings cached values"); + result = m_ipv6AddressCache.getValue(); + rc = Core::ERROR_NONE; + isCacheLoaded = true; + } + } + + if (!isCacheLoaded) + { + if (_networkManager) + { + rc = _networkManager->GetIPSettings(interface, ipversion, result); + /* The value will be cached only for the primary interface IP address. */ + if(Core::ERROR_NONE == rc && m_primaryInterfaceCache.isSet() && (interface == m_primaryInterfaceCache.getValue())) + { + NMLOG_DEBUG("caching the ip address values"); + if (strcasecmp(result.m_ipAddrType.c_str(), "IPv4") == 0) + m_ipv4AddressCache = result; + else if (strcasecmp(result.m_ipAddrType.c_str(), "IPv6") == 0) + m_ipv6AddressCache = result; + } + } + else + { + NMLOG_ERROR("_networkManager == null"); + rc = Core::ERROR_UNAVAILABLE; + } + } if (Core::ERROR_NONE == rc) { @@ -982,6 +1029,7 @@ namespace WPEFramework if (Core::ERROR_NONE == rc) { response["state"] = static_cast (state); + m_wifiStateCache = state; response["success"] = true; } LOG_OUTPARAM(); diff --git a/NetworkManagerRDKProxy.cpp b/NetworkManagerRDKProxy.cpp index d8272132..67052cdc 100644 --- a/NetworkManagerRDKProxy.cpp +++ b/NetworkManagerRDKProxy.cpp @@ -629,7 +629,7 @@ namespace WPEFramework std::vector interfaceList; for (int i = 0; i < list.size; i++) { - NMLOG_INFO ("Interface Name = %s", list.interfaces[i].name); + NMLOG_DEBUG("Interface Name = %s", list.interfaces[i].name); string interfaceName(list.interfaces[i].name); if (("eth0" == interfaceName) || ("wlan0" == interfaceName)) {