Skip to content

RDK-61440: Implementation of handling PowerMode Change in NM plugin #308

Open
Anand73-n wants to merge 16 commits into
developfrom
topic/RDK-61440
Open

RDK-61440: Implementation of handling PowerMode Change in NM plugin #308
Anand73-n wants to merge 16 commits into
developfrom
topic/RDK-61440

Conversation

@Anand73-n
Copy link
Copy Markdown
Contributor

Do not merge.

@Anand73-n Anand73-n requested a review from a team as a code owner May 11, 2026 06:58
Copilot AI review requested due to automatic review settings May 11, 2026 06:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces PowerManager integration to handle DeepSleep-related power mode transitions in the NetworkManager plugin, while also improving thread-safety around default-interface handling and making several robustness fixes (iterator null checks, GLib/libnm context isolation, and deinit hooks). It also bumps the plugin/interface version to 2.2.0 and updates documentation/changelog accordingly.

Changes:

  • Add a new NetworkManagerPowerClient (COMRPC client) and hook it into NetworkManagerImplementation to act on DeepSleep pre-change/changed events.
  • Make default-interface access thread-safe (getDefaultInterface/setDefaultInterface) and update call sites across proxies/connectivity monitor.
  • Improve crash resilience/robustness (null checks on iterator creation, platform deinit functions, GNOME wifi operation serialization, minimal ethernet profile support) and update versioning/docs.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/l2Test/libnm/l2_test_libnmproxy.cpp Minor unit test expectation cleanup / formatting fix.
plugin/rdk/NetworkManagerRDKProxy.cpp Use thread-safe default-interface getters/setters; add iterator null checks; add platform_deinit().
plugin/NetworkManagerPowerClient.h New PowerManager client interface + callback contract for DeepSleep handling.
plugin/NetworkManagerPowerClient.cpp New COMRPC client implementation with an internal worker thread and pre-change ack handling.
plugin/NetworkManagerJsonRpc.cpp Add null checks for iterator creation before invoking implementation APIs.
plugin/NetworkManagerImplementation.h Introduce thread-safe default-interface accessors, PowerManager callback integration, and platform deinit declaration.
plugin/NetworkManagerImplementation.cpp Instantiate PowerManager client; call platform deinit in destructor; use thread-safe default-interface; implement power callbacks.
plugin/NetworkManagerConnectivity.cpp Use thread-safe default-interface access in connectivity monitoring logic.
plugin/gnome/NetworkManagerGnomeWIFI.h Add ethernet-minimal-profile helper; add mutex to serialize wifi operations.
plugin/gnome/NetworkManagerGnomeWIFI.cpp Context push/pop moved to per-operation; serialize operations; add minimal ethernet profile; improve cleanup/error handling.
plugin/gnome/NetworkManagerGnomeProxy.cpp Replace global NMClient with per-instance client/context; add deinit; add migration cleanup + minimal ethernet profile on eth enable.
plugin/gnome/gdbus/NetworkManagerGdbusProxy.cpp Use thread-safe default-interface and add platform_deinit().
plugin/CMakeLists.txt Add ENABLE_POWERMANAGER option, build/link new power client when enabled.
legacy/LegacyWiFiManagerAPIs.cpp Add null check after iterator creation.
legacy/LegacyNetworkAPIs.cpp Add null check after iterator creation.
docs/NetworkManagerPlugin.md Bump documented version to 2.2.0.
definition/NetworkManager.json Bump interface version to 2.2.0.
CMakeLists.txt Bump project version minor to 2 (2.2.0).
CHANGELOG.md Add entries for 2.2.0 and 2.1.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +402 to +403
if(getDefaultInterface() != iface.name)
ReportActiveInterfaceChange(getDefaultInterface(), iface.name);
Comment thread plugin/CMakeLists.txt Outdated
Comment on lines +29 to +34
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 +2226 to +2229
// If there are multiple messages backed up, process a bounded number
// of pending iterations so this path cannot stall indefinitely if the
// context keeps receiving new work.
while (g_main_context_iteration(device_context, FALSE));
Copilot AI review requested due to automatic review settings May 11, 2026 16:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread plugin/NetworkManagerImplementation.cpp Outdated
Comment on lines +1221 to +1224
if (m_wlanEnabled.load() && !m_lastConnectedSSID.empty()) {
NMLOG_INFO("OnPowerModePreChange: waking from DeepSleep — reconnecting to '%s'",
m_lastConnectedSSID.c_str());
ConnectToKnownSSID(m_lastConnectedSSID); // fire-and-forget
Comment thread plugin/NetworkManagerPowerClient.cpp Outdated
Copilot AI review requested due to automatic review settings May 13, 2026 07:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

plugin/NetworkManagerPowerClient.cpp:115

  • Operational(false) stops and joins the power-event thread before unregistering from PowerManager. There is a race window where the COM-RPC dispatcher can still deliver an OnPowerModePreChange after the thread has exited, causing the notification handler to enqueue a PRE_CHANGE event that will never be processed/acked, potentially stalling the power-mode transition. Consider unregistering (or otherwise preventing further notifications / sending an immediate ack) before joining the thread, or making the notification path fast-ack when mStopThread is set.
    } else {
        // Stop the power-event thread before unregistering so any in-flight
        // event that was already enqueued is drained with a fast ack.
        mStopThread = true;
        mQueueCv.notify_one();
        if (mPowerThread.joinable()) {
            mPowerThread.join();
        }
        unregisterEventsAndDeactivate();
    }

Comment thread plugin/NetworkManagerPowerClient.cpp Outdated
Comment thread plugin/NetworkManagerImplementation.cpp Outdated
Comment on lines +1223 to +1227
if (m_ethEnabled.load() && m_ethConnected.load()) {
NMLOG_INFO("OnPowerModePreChange: going to DeepSleep — disconnecting Ethernet");
uint32_t rcEthDown = EthernetDisconnect();
if (rcEthDown == Core::ERROR_NONE) {
m_ethDisconnectedForSleep.store(true);
Comment thread plugin/NetworkManagerImplementation.h Outdated
Comment thread plugin/NetworkManagerPowerClient.cpp Outdated
Comment thread plugin/NetworkManagerPowerClient.cpp
Comment thread plugin/CMakeLists.txt Outdated
Comment on lines +29 to +34
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()
Copilot AI review requested due to automatic review settings May 14, 2026 05:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread plugin/gnome/NetworkManagerGnomeWIFI.cpp
Comment thread plugin/NetworkManagerImplementation.cpp
Copilot AI review requested due to automatic review settings May 19, 2026 06:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

plugin/NetworkManagerImplementation.cpp:1264

  • m_wlanDisconnectedForSleep is cleared before attempting ConnectToKnownSSID(). If the reconnect fails, the flag remains false and subsequent wakeups (or retries) will be skipped even though WiFi was disconnected for sleep. Consider only clearing the flag after a successful reconnect, or restoring it when ConnectToKnownSSID() fails.
                        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);

plugin/NetworkManagerImplementation.cpp:1282

  • m_ethDisconnectedForSleep is cleared before attempting EthernetConnect(). If the reconnect fails, the flag remains false and later logic will assume Ethernet was not disconnected for sleep. Consider clearing this flag only after a successful EthernetConnect(), or restoring it on failure.
                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);

Comment on lines +117 to +120
// Pop the context pushed in createClientNewConnection()
g_main_context_pop_thread_default(m_nmContext);
// Release operation lock acquired in createClientNewConnection()
m_opMutex.unlock();
Comment thread plugin/NetworkManagerImplementation.h Outdated
Comment on lines +230 to +232
uint32_t WiFiDisconnect(void) override;
uint32_t EthernetDisconnect(void);
uint32_t EthernetConnect(void);
Comment on lines +1234 to +1240
if (m_ethEnabled.load() && m_ethConnected.load())
{
NMLOG_INFO("OnPowerModePreChange: going to DeepSleep — disconnecting Ethernet");

uint32_t rcEthDown = EthernetDisconnect();
if (rcEthDown == Core::ERROR_NONE)
{
Copilot AI review requested due to automatic review settings May 21, 2026 06:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (4)

plugin/NetworkManagerImplementation.cpp:1272

  • OnPowerModePreChange calls EthernetConnect(), but there is no corresponding implementation for the RDK/netsrvmgr backend. As-is, non-GNOME builds will fail to link. Either guard this reconnect logic behind the GNOME backend build flag or add a non-GNOME implementation (e.g., returning ERROR_UNAVAILABLE).
                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);

plugin/NetworkManagerImplementation.cpp:1299

  • OnPowerModeChanged calls ReapplyWifiSettings(), which is only implemented in the GNOME/libnm proxy today. This will break non-GNOME builds at link time. Please either guard this call behind the GNOME backend macro or provide an implementation/stub for other backends.
                    NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, triggering active WiFi scan");
                    StartWiFiScan("", nullptr);

                    NMLOG_INFO("OnPowerModeChanged: waking from DeepSleep, toggling auto-route-ext-gw on wlan0");
                    ReapplyWifiSettings();
                }

plugin/gnome/NetworkManagerGnomeWIFI.cpp:538

  • toggleAutoRouteExtGw passes nm_connection_to_dbus(conn, ...) directly into nm_remote_connection_update2 without unref-ing the returned GVariant. Elsewhere in this file (e.g., around line ~1455) the variant is stored and g_variant_unref()'d after the call, suggesting update2 does not take ownership. Please mirror that pattern here to avoid leaking the settings GVariant on each wakeup.
            /* Save to disk */
            m_isSuccess = false;
            nm_remote_connection_update2(remoteConn,
                                         nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL),
                                         NM_SETTINGS_UPDATE2_FLAG_TO_DISK,
                                         NULL, m_cancellable,
                                         onUpdate2Done, this);

plugin/gnome/NetworkManagerGnomeWIFI.cpp:538

  • toggleAutoRouteExtGw intentionally toggles NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW and persists the change to disk (NM_SETTINGS_UPDATE2_FLAG_TO_DISK). Because this is called on every wake, the on-disk connection profile will flip between DEFAULT and TRUE across sleep cycles, which can permanently alter routing behavior and survive reboots. If the goal is only to force a runtime reapply, avoid TO_DISK and/or avoid changing the stored value (e.g., reapply current settings, update in-memory only, or restore the original value after reapply).
            /* Read current value and toggle */
            NMTernary currentVal = NM_TERNARY_DEFAULT;
            g_object_get(s_ip4, NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, &currentVal, NULL);

            NMTernary newVal = (currentVal == NM_TERNARY_DEFAULT) ? NM_TERNARY_TRUE : NM_TERNARY_DEFAULT;
            NMLOG_INFO("toggleAutoRouteExtGw: '%s' auto-route-ext-gw %d -> %d",
                       iface.c_str(), static_cast<int>(currentVal), static_cast<int>(newVal));
            g_object_set(s_ip4, NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, newVal, NULL);

            /* Save to disk */
            m_isSuccess = false;
            nm_remote_connection_update2(remoteConn,
                                         nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL),
                                         NM_SETTINGS_UPDATE2_FLAG_TO_DISK,
                                         NULL, m_cancellable,
                                         onUpdate2Done, this);

Comment thread plugin/NetworkManagerImplementation.h Outdated
Comment on lines +230 to +233
uint32_t WiFiDisconnect(void) override;
uint32_t EthernetDisconnect(void);
uint32_t EthernetConnect(void);
uint32_t ReapplyWifiSettings(void);
Comment thread plugin/NetworkManagerImplementation.cpp Outdated
Comment on lines +1228 to +1232
uint32_t rcEthDown = EthernetDisconnect();
if (rcEthDown == Core::ERROR_NONE)
{
m_ethDisconnectedForSleep.store(true);
}
Comment on lines +1132 to +1133
if(wifi->activateKnownConnection(nmUtils::ethIface(), "Wired connection 1"))
rc = Core::ERROR_NONE;
if (error) {
NMLOG_ERROR("Could not connect to NetworkManager: %s.", error->message);
g_error_free(error);
}
anandn654 added 10 commits May 23, 2026 05:13
Reason for change: Ctrl ntwrk state based on PowerMode transitions
Test procedure: Change the PowerMode state and verify the behavior
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: Add log to know cliendId
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: fix crash from power worker thread
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: offload prechange WiFi disc to dedicated powerthrd
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: enabled ConnectToKnownSSID()
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: trigger normal WiFi scan on DeepSleep wakeup with
Network Standby ON to handle AP channel changes
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: check before initiating wifi connect and disconnect
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: Disconnect ethernet on DeepSleep entry and
reconnect on wakeup OnPowerModePreChange
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: guard ethernet wakeup reconnect with m_ethDisconnectedForSleep
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: guard wifi wakeup reconnect with m_wlanDisconnectedForSleep
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
anandn654 added 6 commits May 23, 2026 05:13
Reason for change: Additional logging and code alignment
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: Fix for trigger Wi-Fi scan OnPowerMode Changed
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: code cleanup
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: code cleanup
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: reapply wlan0 on wakeup from DeepSleep with NSM ON
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Reason for change: On wakeup from DeepSleep with Network Standby ON,
request DHCP lease for both wlan0 and eth0.
Test procedure: Change the PowerMode and verify the log
Risks: low
Priority: P1

Signed-off-by: Anand N <Anand_N@comcast.com>
Copilot AI review requested due to automatic review settings May 23, 2026 05:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Comment on lines 45 to 53
wifiManager::wifiManager() : m_client(nullptr), m_loop(nullptr), m_createNewConnection(false), m_objectPath(nullptr), m_wifidevice(nullptr), m_source(nullptr), m_cancellable(nullptr){
NMLOG_INFO("wifiManager");
m_nmContext = g_main_context_new();
g_main_context_push_thread_default(m_nmContext);
// g_main_context_push_thread_default(m_nmContext);
// Do NOT push m_nmContext here. Pushing here permanently locks ownership
// to the constructor thread (owner_count stays at 1, never released).
// All callers — must push/pop around
// each createClientNewConnection()/deleteClientConnection() pair instead.
m_loop = g_main_loop_new(m_nmContext, FALSE);
Comment on lines +537 to +543
/* Save to disk */
m_isSuccess = false;
nm_remote_connection_update2(remoteConn,
nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL),
NM_SETTINGS_UPDATE2_FLAG_TO_DISK,
NULL, m_cancellable,
settingsSavedCb, this);
{
NMLOG_INFO("OnPowerModeChanged: current=%d new=%d",
static_cast<int>(currentState), static_cast<int>(newState));
if (currentState == Exchange::IPowerManager::POWER_STATE_STANDBY_DEEP_SLEEP) {
Comment on lines 326 to 330
std::atomic<bool> m_stopThread{false};
std::mutex m_condVariableMutex;
std::condition_variable m_condVariable;
std::unique_ptr<NetworkManagerPowerClient> _powerClient;
public:
Comment on lines +1182 to +1198
/* No-op on RDK platform */
NMLOG_INFO("EthernetDeactivate: no-op on RDK platform");
return Core::ERROR_NONE;
}

uint32_t NetworkManagerImplementation::EthernetActivate(void)
{
/* No-op on RDK platform */
NMLOG_INFO("EthernetActivate: no-op on RDK platform");
return Core::ERROR_NONE;
}

uint32_t NetworkManagerImplementation::RequestDHCPLease(const string& iface)
{
/* No-op on RDK platform */
NMLOG_INFO("RequestDHCPLease: no-op on RDK platform (iface=%s)", iface.c_str());
return Core::ERROR_NONE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants