Skip to content

Commit

Permalink
DELIA-65737: Wi-Fi interface shows IP even after Wi-Fi is disconnected (
Browse files Browse the repository at this point in the history
rdkcentral#1)

Implemented a cache logic to handle redundant calls  
* update the review comments
  • Loading branch information
cmuhammedrafi authored Oct 7, 2024
1 parent a10964d commit bb42fa7
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 13 deletions.
2 changes: 1 addition & 1 deletion NetworkManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
62 changes: 60 additions & 2 deletions NetworkManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <string>
#include <atomic>
#include <mutex>

namespace WPEFramework
{
Expand Down Expand Up @@ -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
Expand All @@ -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);
}

Expand All @@ -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
Expand Down Expand Up @@ -184,6 +194,7 @@ namespace WPEFramework
JsonObject result;
result["state"] = static_cast <int> (state);
_parent.Notify("onWiFiStateChange", result);
_parent.m_wifiStateCache = state;
}

void onWiFiSignalStrengthChange(const string ssid, const string signalLevel, const Exchange::INetworkManager::WiFiSignalQuality signalQuality) override
Expand Down Expand Up @@ -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<typename CacheValue>
class Cache {
public:
Cache() : is_set(false) {}

Cache& operator=(const CacheValue& value) {
std::lock_guard<std::mutex> lock(mutex);
this->value = value;
is_set.store(true);
return *this;
}

Cache& operator=(CacheValue&& value) {
std::lock_guard<std::mutex> 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<std::mutex> lock(mutex);
return value;
}

CacheValue& getValue() {
std::lock_guard<std::mutex> lock(mutex);
return value;
}

private:
CacheValue value;
std::atomic<bool> is_set;
mutable std::mutex mutex;
};

// cached varibales
Cache<Exchange::INetworkManager::WiFiState> m_wifiStateCache;
Cache<Exchange::INetworkManager::IPAddressInfo> m_ipv4AddressCache;
Cache<Exchange::INetworkManager::IPAddressInfo> m_ipv6AddressCache;
Cache<std::string> m_primaryInterfaceCache;
private:
// Notification/event handlers
// Clean up when we're told to deactivate
Expand Down Expand Up @@ -315,7 +374,6 @@ namespace WPEFramework
Exchange::INetworkManager *_networkManager;
Core::Sink<Notification> _notification;
string m_publicIPAddress;
string m_defaultInterface;
string m_publicIPAddressType;
};
}
Expand Down
66 changes: 57 additions & 9 deletions NetworkManagerJsonRpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,21 @@ 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;

if (Core::ERROR_NONE == rc)
{
response["interface"] = interface;
m_defaultInterface = interface;
m_primaryInterfaceCache = interface;
response["success"] = true;
}
LOG_OUTPARAM();
Expand Down Expand Up @@ -278,23 +284,64 @@ namespace WPEFramework
uint32_t rc = Core::ERROR_GENERAL;
string interface = "";
string ipversion = "";
bool isCacheLoaded = false;
Exchange::INetworkManager::IPAddressInfo result{};

if (parameters.HasLabel("interface"))
interface = parameters["interface"].String();
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)
{
Expand Down Expand Up @@ -982,6 +1029,7 @@ namespace WPEFramework
if (Core::ERROR_NONE == rc)
{
response["state"] = static_cast <int> (state);
m_wifiStateCache = state;
response["success"] = true;
}
LOG_OUTPARAM();
Expand Down
2 changes: 1 addition & 1 deletion NetworkManagerRDKProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ namespace WPEFramework
std::vector<InterfaceDetails> 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))
{
Expand Down

0 comments on commit bb42fa7

Please sign in to comment.