Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ find_package(${NAMESPACE}Core REQUIRED)
find_package(${NAMESPACE}Plugins REQUIRED)
find_package(CURL)

option(ENABLE_POWERMANAGER "Enable PowerManager COMRPC integration for DeepSleep WiFi management" ON)
if(ENABLE_POWERMANAGER)
find_package(${NAMESPACE}Definitions REQUIRED)
add_definitions(-DENABLE_POWERMANAGER)
message("NetworkManager: PowerManager integration enabled")
endif()
Comment on lines +29 to +34
Comment on lines +29 to +34

if (USE_RDK_LOGGER)
find_package(rdklogger REQUIRED)
add_definitions(-DUSE_RDK_LOGGER)
Expand Down Expand Up @@ -83,6 +90,11 @@ add_library(${MODULE_IMPL_NAME} SHARED
NetworkManagerLogger.cpp
Module.cpp)

if(ENABLE_POWERMANAGER)
target_sources(${MODULE_IMPL_NAME} PRIVATE NetworkManagerPowerClient.cpp)
target_link_libraries(${MODULE_IMPL_NAME} PRIVATE ${NAMESPACE}Definitions::${NAMESPACE}Definitions)
endif()

if(ENABLE_GNOME_NETWORKMANAGER)
if(ENABLE_GNOME_GDBUS)
message("networkmanager building with gdbus")
Expand Down
131 changes: 131 additions & 0 deletions plugin/NetworkManagerImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <thread>
#include <chrono>
#include "NetworkManagerImplementation.h"
#ifdef ENABLE_POWERMANAGER
#include "NetworkManagerPowerClient.h"
#endif

#if USE_TELEMETRY
#include "NetworkManagerJsonEnum.h"
Expand Down Expand Up @@ -54,6 +57,8 @@ namespace WPEFramework
m_wlanConnected.store(false);
m_ethEnabled.store(false);
m_wlanEnabled.store(false);
m_ethDisconnectedForSleep.store(false);
m_wlanDisconnectedForSleep.store(false);

/* Set NetworkManager Out-Process name to be NWMgrPlugin */
Core::ProcessInfo().Name("NWMgrPlugin");
Expand All @@ -71,6 +76,9 @@ namespace WPEFramework
NetworkManagerImplementation::~NetworkManagerImplementation()
{
NMLOG_INFO("NetworkManager Out-Of-Process Shutdown/Cleanup");
#ifdef ENABLE_POWERMANAGER
_powerClient.reset();
#endif
connectivityMonitor.stopConnectivityMonitor();
_instance = nullptr;
platform_deinit();
Expand Down Expand Up @@ -199,6 +207,9 @@ namespace WPEFramework
NetworkManagerImplementation::platform_init();
/* change gnome networkmanager or netsrvmgr logg level */
NetworkManagerImplementation::platform_logging(static_cast <NetworkManagerLogger::LogLevel>(config.loglevel.Value()));
#ifdef ENABLE_POWERMANAGER
_powerClient.reset(new NetworkManagerPowerClient(*this));
#endif
return(Core::ERROR_NONE);
}

Expand Down Expand Up @@ -1184,5 +1195,125 @@ namespace WPEFramework
}
#endif
}

#ifdef ENABLE_POWERMANAGER
void NetworkManagerImplementation::OnPowerModePreChange(
const Exchange::IPowerManager::PowerState currentState,
const Exchange::IPowerManager::PowerState newState,
std::function<void()> sendAck)
{
// Called from NetworkManagerPowerClient's power thread.
// Policy (standbyMode check, DeepSleep filter) has already been
// applied by the power thread before calling here.
NMLOG_INFO("OnPowerModePreChange: current=%d new=%d",
static_cast<int>(currentState), static_cast<int>(newState));

using PowerState = Exchange::IPowerManager::PowerState;

if (newState != PowerState::POWER_STATE_STANDBY_DEEP_SLEEP &&
currentState != PowerState::POWER_STATE_STANDBY_DEEP_SLEEP)
{
NMLOG_INFO("OnPowerModePreChange: not entering or exiting DeepSleep, no action needed");
sendAck();
return;
}

if (newState == PowerState::POWER_STATE_STANDBY_DEEP_SLEEP)
{
if (m_wlanEnabled.load() && m_wlanConnected.load())
{
NMLOG_INFO("OnPowerModePreChange: going to DeepSleep — disconnecting WiFi");

uint32_t rcWifiDown = WiFiDisconnect();
if (rcWifiDown == Core::ERROR_NONE)
{
m_wlanDisconnectedForSleep.store(true);
}
else
{
NMLOG_WARNING("OnPowerModePreChange: WiFiDisconnect failed (rc=%u), will not reconnect on wakeup", rcWifiDown);
}
}
else
{
NMLOG_WARNING("OnPowerModePreChange: going to DeepSleep — WiFi not connected, skipping disconnect");
}

if (m_ethEnabled.load() && m_ethConnected.load())
{
NMLOG_INFO("OnPowerModePreChange: going to DeepSleep — disconnecting Ethernet");

uint32_t rcEthDown = EthernetDisconnect();
if (rcEthDown == Core::ERROR_NONE)
{
Comment thread
Anand73-n marked this conversation as resolved.
m_ethDisconnectedForSleep.store(true);
}
else
{
NMLOG_WARNING("OnPowerModePreChange: EthernetDisconnect failed (rc=%u), will not reconnect on wakeup", rcEthDown);
}
}
else
{
NMLOG_WARNING("OnPowerModePreChange: going to DeepSleep — Ethernet not connected, skipping disconnect");
}
}
else if (currentState == PowerState::POWER_STATE_STANDBY_DEEP_SLEEP)
{
if (m_wlanDisconnectedForSleep.load())
{
if (!m_lastConnectedSSID.empty())
{
NMLOG_INFO("OnPowerModePreChange: waking from DeepSleep — reconnecting to '%s'",
m_lastConnectedSSID.c_str());
m_wlanDisconnectedForSleep.store(false);
uint32_t rcWifiUp = ConnectToKnownSSID(m_lastConnectedSSID);
if (rcWifiUp != Core::ERROR_NONE)
NMLOG_WARNING("OnPowerModePreChange: ConnectToKnownSSID failed (rc=%u)", rcWifiUp);
}
else
{
NMLOG_WARNING("OnPowerModePreChange: waking from DeepSleep — no last SSID, skipping reconnect");
}
}
else
{
NMLOG_INFO("OnPowerModePreChange: waking from DeepSleep — WiFi was not connected or was already down before sleep, skipping reconnect");
}

if (m_ethDisconnectedForSleep.load())
{
m_ethDisconnectedForSleep.store(false);
NMLOG_INFO("OnPowerModePreChange: waking from DeepSleep — reconnecting Ethernet");
uint32_t rcEthUp = EthernetConnect();
if (rcEthUp != Core::ERROR_NONE)
NMLOG_WARNING("OnPowerModePreChange: EthernetConnect failed (rc=%u)", rcEthUp);
}
else
{
NMLOG_INFO("OnPowerModePreChange: waking from DeepSleep — Ethernet was not connected or was already down before sleep, skipping reconnect");
}
}
sendAck();
}

void NetworkManagerImplementation::OnPowerModeChanged(
const Exchange::IPowerManager::PowerState currentState,
const Exchange::IPowerManager::PowerState newState)
{
NMLOG_INFO("OnPowerModeChanged: current=%d new=%d",
static_cast<int>(currentState), static_cast<int>(newState));
if (currentState == Exchange::IPowerManager::POWER_STATE_STANDBY_DEEP_SLEEP) {
// Waking from DeepSleep with Network Standby ON: the AP may have
// changed channel while the device slept (802.11 CSA). Trigger an
// active scan so the driver discovers the AP on its new channel.
if (m_wlanEnabled.load() && m_wlanConnected.load())
{
NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, triggering active WiFi scan");
StartWiFiScan("", nullptr);
}
}
}
#endif // ENABLE_POWERMANAGER
}
}
24 changes: 24 additions & 0 deletions plugin/NetworkManagerImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ using namespace std;
#include "NetworkManagerLogger.h"
#include "NetworkManagerConnectivity.h"
#include "NetworkManagerStunClient.h"
#ifdef ENABLE_POWERMANAGER
#include "NetworkManagerPowerClient.h"
#endif

/* Forward declarations to avoid pulling GLib/libnm headers into this header */
typedef struct _NMClient NMClient;
Expand Down Expand Up @@ -63,6 +66,9 @@ namespace WPEFramework
namespace Plugin
{
class NetworkManagerImplementation : public Exchange::INetworkManager
#ifdef ENABLE_POWERMANAGER
, public INetworkPowerCallback
#endif
{
enum NetworkEvents
{
Expand Down Expand Up @@ -226,6 +232,10 @@ namespace WPEFramework

uint32_t WiFiConnect(const WiFiConnectTo& ssid /* @in */) override;
uint32_t WiFiDisconnect(void) override;
#ifdef ENABLE_POWERMANAGER
uint32_t EthernetDisconnect(void);
uint32_t EthernetConnect(void);
Comment thread
Anand73-n marked this conversation as resolved.
#endif //ENABLE_POWERMANAGER
uint32_t GetConnectedSSID(WiFiSSIDInfo& ssidInfo /* @out */) override;

uint32_t StartWPS(const WiFiWPS& method /* @in */, const string& wps_pin /* @in */) override;
Expand Down Expand Up @@ -277,6 +287,15 @@ namespace WPEFramework
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);

#ifdef ENABLE_POWERMANAGER
// INetworkPowerCallback overrides
void OnPowerModePreChange(const Exchange::IPowerManager::PowerState currentState,
const Exchange::IPowerManager::PowerState newState,
std::function<void()> sendAck) override;
void OnPowerModeChanged(const Exchange::IPowerManager::PowerState currentState,
const Exchange::IPowerManager::PowerState newState) override;
#endif

private:
void platform_init(void);
void platform_deinit(void);
Expand Down Expand Up @@ -314,6 +333,9 @@ namespace WPEFramework
std::atomic<bool> m_stopThread{false};
std::mutex m_condVariableMutex;
std::condition_variable m_condVariable;
#ifdef ENABLE_POWERMANAGER
std::unique_ptr<NetworkManagerPowerClient> _powerClient;
#endif
public:
IPAddress m_ethIPv4Address;
IPAddress m_wlanIPv4Address;
Expand All @@ -323,6 +345,8 @@ namespace WPEFramework
std::atomic<bool> m_wlanConnected;
std::atomic<bool> m_ethEnabled;
std::atomic<bool> m_wlanEnabled;
std::atomic<bool> m_ethDisconnectedForSleep;
std::atomic<bool> m_wlanDisconnectedForSleep;
std::string m_lastConnectedSSID;
NMClient *m_nmClient{nullptr}; /* proxy NMClient — bound to m_nmContext */
GMainContext *m_nmContext{nullptr}; /* isolated context, not the global default */
Expand Down
Loading
Loading