Skip to content
Merged
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
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/"

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

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

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

- name: Generate IARM headers
run: |
touch install/usr/lib/libIARMBus.so
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ get_directory_property(SEVICES_DEFINES COMPILE_DEFINITIONS)
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(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.

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

if(ENABLE_GNOME_NETWORKMANAGER)
Expand Down
124 changes: 124 additions & 0 deletions plugin/NetworkManagerImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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 @@ -61,6 +63,7 @@ namespace WPEFramework
NetworkManagerImplementation::~NetworkManagerImplementation()
{
NMLOG_INFO("NetworkManager Out-Of-Process Shutdown/Cleanup");
m_powerClient.reset();
connectivityMonitor.stopConnectivityMonitor();
_instance = nullptr;
if(m_registrationThread.joinable())
Expand Down Expand Up @@ -188,6 +191,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);
}

Expand Down Expand Up @@ -1122,5 +1126,125 @@ namespace WPEFramework
}
_notificationLock.Unlock();
}

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

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);
}
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)
{
m_ethDisconnectedForSleep.store(true);
}
else
{
NMLOG_ERROR("OnPowerModePreChange: EthernetDeactivate failed (rc=%u), will not activate on wakeup", rcEthDown);
}
}
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());
Exchange::INetworkManager::WiFiConnectTo connectInfo{};
uint32_t rcWifiUp = WiFiConnect(connectInfo);
if (rcWifiUp == Core::ERROR_NONE)
{
m_wlanDisconnectedForSleep.store(false);
}
else
{
NMLOG_ERROR("OnPowerModePreChange: WiFiConnect failed (rc=%u)", rcWifiUp);
}
}
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) != 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.
}
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");
}
}
}
}
}
}
16 changes: 16 additions & 0 deletions plugin/NetworkManagerImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@
#include <arpa/inet.h>
#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"

/*
* Receiver thermal noise + BW factor + assumed noise figure (NF) (dB)
Expand All @@ -58,6 +61,7 @@ namespace WPEFramework
namespace Plugin
{
class NetworkManagerImplementation : public Exchange::INetworkManager
, public INetworkPowerCallback
{
enum NetworkEvents
{
Expand Down Expand Up @@ -220,6 +224,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);
uint32_t GetConnectedSSID(WiFiSSIDInfo& ssidInfo /* @out */) override;

uint32_t StartWPS(const WiFiWPS& method /* @in */, const string& wps_pin /* @in */) override;
Expand Down Expand Up @@ -270,6 +276,13 @@ namespace WPEFramework
void ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state);
void ReportWiFiSignalQualityChange(const string ssid, const int strength, const int noise, const int snr, const Exchange::INetworkManager::WiFiSignalQuality quality);

// 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_logging(const NetworkManagerLogger::LogLevel& level);
Expand Down Expand Up @@ -306,6 +319,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:
IPAddress m_ethIPv4Address;
IPAddress m_wlanIPv4Address;
Expand All @@ -316,6 +330,8 @@ namespace WPEFramework
std::atomic<bool> m_ethEnabled;
std::atomic<bool> m_wlanEnabled;
string m_defaultInterface;
std::atomic<bool> m_ethDisconnectedForSleep;
std::atomic<bool> m_wlanDisconnectedForSleep;
std::string m_lastConnectedSSID;
mutable ConnectivityMonitor connectivityMonitor;
};
Expand Down
Loading
Loading