Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
51b98b0
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 2, 2026
b546d29
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 4, 2026
6c7be38
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 5, 2026
4d59a20
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 6, 2026
7c8996e
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 6, 2026
524ce4c
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 11, 2026
28058da
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 11, 2026
b66c970
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 13, 2026
cb9c505
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 13, 2026
5be7870
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 13, 2026
707e810
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 14, 2026
1ec7b2a
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 15, 2026
830cff9
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 19, 2026
394a9f4
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 21, 2026
49a38c3
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 21, 2026
400f9a3
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 22, 2026
7936e2f
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 25, 2026
f35ea06
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 26, 2026
a8db4bd
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 26, 2026
312f095
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 27, 2026
6983a70
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 27, 2026
3364775
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 27, 2026
40a8d16
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 28, 2026
95697c2
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 28, 2026
51b6661
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 28, 2026
f649b91
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 28, 2026
9bd0963
Include NetworkManagerPowerClient.cpp to the builds
karuna2git May 28, 2026
9d2380c
Merge branch 'develop' into topic/RDK-61440
karuna2git May 28, 2026
13d5b8a
updated to not to include external files
karuna2git May 28, 2026
3aada97
RDK-61440: Implementation of handling PowerMode Change in NM plugin
anandn654 May 29, 2026
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
5 changes: 5 additions & 0 deletions .github/workflows/gdbus_proxy_L1_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ jobs:
&&
cmake --build build/ThunderInterfaces --target install -j8

- name: Install IPowerManager header
run: |
IFACE_DIR=$(find ${{github.workspace}}/install/usr/include -maxdepth 2 -name "interfaces" -type d | head -1)
cp ${{github.workspace}}/networkmanager/tests/mocks/thunder/IPowerManager.h "$IFACE_DIR/"

Comment thread
karuna2git marked this conversation as resolved.
- name: Build networkmanager with Gnome GDBUS Proxy
run: >
cmake
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/legacy_L1_L2_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ jobs:
&&
cmake --build build/ThunderInterfaces --target install -j8

- name: Install IPowerManager header
run: |
IFACE_DIR=$(find ${{github.workspace}}/install/usr/include -maxdepth 2 -name "interfaces" -type d | head -1)
cp ${{github.workspace}}/networkmanager/tests/mocks/thunder/IPowerManager.h "$IFACE_DIR/"
Comment thread
karuna2git marked this conversation as resolved.

- name: Generate IARM headers
run: |
touch install/usr/lib/libIARMBus.so
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/libnm_proxy_L1_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ env:
jobs:
L1-tests:
name: Build and run unit tests
runs-on: ubuntu-22.04
# Note: Ubuntu 24.04 is required for libnm 1.46 which is needed for NetworkManagerPowerClient support
runs-on: ubuntu-24.04

steps:
# Set up Thunder cache
Expand Down Expand Up @@ -107,6 +108,11 @@ jobs:
&&
cmake --build build/ThunderInterfaces --target install -j8

- name: Install IPowerManager header
run: |
IFACE_DIR=$(find ${{github.workspace}}/install/usr/include -maxdepth 2 -name "interfaces" -type d | head -1)
cp ${{github.workspace}}/networkmanager/tests/mocks/thunder/IPowerManager.h "$IFACE_DIR/"

Comment thread
karuna2git marked this conversation as resolved.
- name: Generate dependency files
run: |
sudo bash -c 'echo "ETHERNET_INTERFACE=eth0
Expand Down Expand Up @@ -160,7 +166,7 @@ jobs:

- name: Generate coverage
run: |
lcov -c -o coverage.info -d build/networkmanager_libnm/
lcov --rc geninfo_unexecuted_blocks=1 -c -o coverage.info -d build/networkmanager_libnm/ --ignore-errors mismatch
lcov -e coverage.info '*/networkmanager/plugin/gnome/*' -o filtered_coverage.info

- name: Generate the html report
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/rdk_proxy_L1_L2_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ jobs:
&&
cmake --build build/ThunderInterfaces --target install -j8

- name: Install IPowerManager header
run: |
IFACE_DIR=$(find ${{github.workspace}}/install/usr/include -maxdepth 2 -name "interfaces" -type d | head -1)
cp ${{github.workspace}}/networkmanager/tests/mocks/thunder/IPowerManager.h "$IFACE_DIR/"
Comment thread
Anand73-n marked this conversation as resolved.

- name: Generate IARM headers
run: |
touch install/usr/lib/libIARMBus.so
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ option(ENABLE_LEGACY_PLUGINS "Enable Legacy Plugins" ON)
option(USE_RDK_LOGGER "Enable RDK Logger for logging" OFF )
option(ENABLE_UNIT_TESTING "Enable unit tests" OFF)
option(USE_TELEMETRY "Enable Telemetry T2 support" OFF)
option(ENABLE_ETHERNET_CONNECTION_HANDLING
"Enable pre-sleep Ethernet deactivation" OFF)

if(ENABLE_ETHERNET_CONNECTION_HANDLING)
add_definitions(-DENABLE_ETHERNET_CONNECTION_HANDLING)
message(STATUS "Ethernet connection handling: enabled")
endif()
Comment thread
Anand73-n marked this conversation as resolved.

if (USE_TELEMETRY)
find_package(T2 REQUIRED)
Expand Down
1 change: 1 addition & 0 deletions plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ add_library(${MODULE_IMPL_NAME} SHARED
NetworkManagerConnectivity.cpp
NetworkManagerStunClient.cpp
NetworkManagerLogger.cpp
NetworkManagerPowerClient.cpp
Module.cpp)

if(ENABLE_GNOME_NETWORKMANAGER)
Expand Down
125 changes: 125 additions & 0 deletions plugin/NetworkManagerImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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 +73,7 @@ namespace WPEFramework
NetworkManagerImplementation::~NetworkManagerImplementation()
{
NMLOG_INFO("NetworkManager Out-Of-Process Shutdown/Cleanup");
m_powerClient.reset();
connectivityMonitor.stopConnectivityMonitor();
_instance = nullptr;
platform_deinit();
Expand Down Expand Up @@ -199,6 +202,7 @@ namespace WPEFramework
NetworkManagerImplementation::platform_init();
/* change gnome networkmanager or netsrvmgr logg level */
NetworkManagerImplementation::platform_logging(static_cast <NetworkManagerLogger::LogLevel>(config.loglevel.Value()));
m_powerClient.reset(new NetworkManagerPowerClient(*this));
return(Core::ERROR_NONE);
Comment thread
Anand73-n marked this conversation as resolved.
}

Expand Down Expand Up @@ -1197,5 +1201,126 @@ namespace WPEFramework
}
#endif
}

void NetworkManagerImplementation::OnPowerModePreChange(
const Exchange::IPowerManager::PowerState currentState,
const Exchange::IPowerManager::PowerState newState,
std::function<void()> sendAck)
{
// Called from NetworkManagerPowerClient's power thread.
NMLOG_DEBUG("OnPowerModePreChange: current=%d new=%d",
static_cast<int>(currentState), static_cast<int>(newState));
Comment thread
Anand73-n marked this conversation as resolved.

Comment thread
Anand73-n marked this conversation as resolved.
using PowerState = Exchange::IPowerManager::PowerState;

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);
m_wlanConnected.store(false);
}
else
{
NMLOG_ERROR("OnPowerModePreChange: WiFiDisconnect failed (rc=%u), will not reconnect on wakeup", rcWifiDown);
}
}
else
{
NMLOG_DEBUG("OnPowerModePreChange: going to DeepSleep — WiFi not connected, skipping disconnect");
}
#ifdef ENABLE_ETHERNET_CONNECTION_HANDLING
if (m_ethEnabled.load() && m_ethConnected.load())
{
NMLOG_INFO("OnPowerModePreChange: going to DeepSleep — deactivating Ethernet");

uint32_t rcEthDown = EthernetDeactivate();
if (rcEthDown == Core::ERROR_NONE)
Comment thread
Anand73-n marked this conversation as resolved.
{
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
m_ethDisconnectedForSleep.store(true);
}
else
{
NMLOG_ERROR("OnPowerModePreChange: EthernetDeactivate failed (rc=%u), will not activate on wakeup", rcEthDown);
}
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
}
else
{
NMLOG_DEBUG("OnPowerModePreChange: going to DeepSleep — Ethernet not activated, skipping deactivate");
}
#endif
}
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());
uint32_t rcWifiUp = ConnectToKnownSSID(m_lastConnectedSSID);
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
if (rcWifiUp == Core::ERROR_NONE)
{
m_wlanDisconnectedForSleep.store(false);
m_wlanConnected.store(true); // Mark WiFi as connected.
}
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
else
{
NMLOG_ERROR("OnPowerModePreChange: ConnectToKnownSSID failed (rc=%u)", rcWifiUp);
}
Comment thread
Anand73-n marked this conversation as resolved.
}
else
{
NMLOG_INFO("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");
}
}
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::PowerState::POWER_STATE_STANDBY_DEEP_SLEEP) {

if (m_wlanEnabled.load() && m_wlanConnected.load())
{
// 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.
NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, triggering active WiFi scan");
if (StartWiFiScan(nullptr, nullptr) != Core::ERROR_NONE)
{
NMLOG_ERROR("OnPowerModeChanged: StartWiFiScan failed");
}

NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, requesting DHCP lease on wlan0");
if (ReacquireDHCPLease("wlan0") != Core::ERROR_NONE)
{
NMLOG_ERROR("OnPowerModeChanged: ReacquireDHCPLease(wlan0) failed");
Comment thread
Anand73-n marked this conversation as resolved.
}
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
}
if (m_ethEnabled.load() && m_ethConnected.load())
{
NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, requesting DHCP lease on eth0");
if (ReacquireDHCPLease("eth0") != Core::ERROR_NONE)
{
NMLOG_ERROR("OnPowerModeChanged: ReacquireDHCPLease(eth0) failed");
}
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
karuna2git marked this conversation as resolved.
}
}
}
}
}
15 changes: 15 additions & 0 deletions plugin/NetworkManagerImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
#include <linux/rtnetlink.h>
#include <atomic>
#include <mutex>
#include <memory>

using namespace std;

#include "INetworkManager.h"
#include "NetworkManagerLogger.h"
#include "NetworkManagerConnectivity.h"
#include "NetworkManagerStunClient.h"
#include "NetworkManagerPowerClient.h"

/* Forward declarations to avoid pulling GLib/libnm headers into this header */
typedef struct _NMClient NMClient;
Expand Down Expand Up @@ -63,6 +65,7 @@ namespace WPEFramework
namespace Plugin
{
class NetworkManagerImplementation : public Exchange::INetworkManager
, public INetworkPowerCallback
{
enum NetworkEvents
{
Expand Down Expand Up @@ -226,6 +229,8 @@ namespace WPEFramework

uint32_t WiFiConnect(const WiFiConnectTo& ssid /* @in */) override;
uint32_t WiFiDisconnect(void) override;
uint32_t EthernetDeactivate(void);
uint32_t ReacquireDHCPLease(const string& iface);
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
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 +282,13 @@ 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);

// 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;

private:
void platform_init(void);
void platform_deinit(void);
Expand Down Expand Up @@ -314,6 +326,7 @@ namespace WPEFramework
std::atomic<bool> m_stopThread{false};
std::mutex m_condVariableMutex;
std::condition_variable m_condVariable;
std::unique_ptr<NetworkManagerPowerClient> m_powerClient;
public:
Comment thread
Anand73-n marked this conversation as resolved.
Comment thread
Anand73-n marked this conversation as resolved.
IPAddress m_ethIPv4Address;
IPAddress m_wlanIPv4Address;
Expand All @@ -323,6 +336,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