wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_update_power_mode.cpp
changeset 0 c40eb8fe8501
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_update_power_mode.cpp	Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,254 @@
+/*
+* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Statemachine for updating power mode
+*
+*/
+
+
+#include "core_operation_update_power_mode.h"
+#include "core_server.h"
+#include "core_tools.h"
+#include "am_debug.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_update_power_mode_c::core_operation_update_power_mode_c(
+    u32_t request_id,
+    core_server_c* server,
+    abs_core_driverif_c* drivers,
+    abs_core_server_callback_c* adaptation ) :
+    core_operation_base_c( core_operation_update_power_mode, request_id, server, drivers, adaptation,
+        core_base_flag_connection_needed | core_base_flag_only_one_instance ),
+    preferred_mode_m(
+        server_m->get_core_settings().preferred_power_save_mode() ),
+    power_mode_m( CORE_POWER_MODE_CAM )
+    {
+    DEBUG( "core_operation_update_power_mode_c::core_operation_update_power_mode_c()" );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_update_power_mode_c::core_operation_update_power_mode_c(
+    u32_t request_id,
+    core_server_c* server,
+    abs_core_driverif_c* drivers,
+    abs_core_server_callback_c* adaptation,
+    const core_power_save_mode_s& mode ) :
+    core_operation_base_c( core_operation_update_power_mode, request_id, server, drivers, adaptation,
+        core_base_flag_connection_needed | core_base_flag_only_one_instance ),
+    preferred_mode_m( mode ),
+    power_mode_m( CORE_POWER_MODE_CAM )
+    {
+    DEBUG( "core_operation_update_power_mode_c::core_operation_update_power_mode_c()" );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_update_power_mode_c::~core_operation_update_power_mode_c()
+    {
+    DEBUG( "core_operation_update_power_mode_c::~core_operation_update_power_mode_c()" );
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_update_power_mode_c::next_state()
+    {
+    DEBUG( "core_operation_update_power_mode_c::next_state()" );
+    
+    switch ( operation_state_m )
+        {
+        case core_state_init:
+            {
+            operation_state_m = core_state_req_set_power_mode;
+
+            if ( !server_m->get_core_settings().is_driver_loaded() ||
+                 !server_m->get_connection_data() )
+                {
+                DEBUG( "core_operation_update_power_mode_c::next_state() - not connected, no reason to set power save mode" );
+
+                return core_error_ok;
+                }
+
+            /**
+             * Determine the correct mode to use.
+             */
+            power_mode_m = determine_power_mode();
+
+            const core_power_mode_s& current_mode(
+                server_m->get_core_settings().power_mode() );
+
+            if( power_mode_m.mode == current_mode.mode &&
+                power_mode_m.wakeup_mode_light == current_mode.wakeup_mode_light &&
+                power_mode_m.wakeup_interval_light == current_mode.wakeup_interval_light &&
+                power_mode_m.wakeup_mode_deep == current_mode.wakeup_mode_deep &&
+                power_mode_m.wakeup_interval_deep == current_mode.wakeup_interval_deep )                
+                {
+                DEBUG1( "core_operation_update_power_mode_c::next_state() - power save mode (%u) already set",
+                    power_mode_m.mode );
+
+                return core_error_ok;
+                }
+
+#ifdef _DEBUG
+            if( power_mode_m.mode == core_power_mode_cam )
+                {
+                DEBUG( "core_operation_update_power_mode_c::next_state() - setting power mode to core_power_mode_cam" );
+                }
+            else
+                {
+                DEBUG4( "core_operation_update_power_mode_c::next_state() - setting power mode to core_power_mode_ps (light %u, %u) (deep %u, %u)",
+                    power_mode_m.wakeup_mode_light, power_mode_m.wakeup_interval_light,
+                    power_mode_m.wakeup_mode_deep, power_mode_m.wakeup_interval_deep );
+                }
+#endif // _DEBUG
+
+            drivers_m->set_power_mode(
+                request_id_m,
+                power_mode_m );
+
+            break;
+            }
+        case core_state_req_set_power_mode:
+            {
+            DEBUG1( "core_operation_update_power_mode_c::next_state() - power save mode (%u) successfully set",
+                power_mode_m.mode );
+
+            server_m->get_core_settings().set_power_mode( power_mode_m );
+
+            return core_error_ok;
+            }
+        default:
+            {
+            ASSERT( false_t );
+            }
+        }
+
+    return core_error_request_pending;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_power_mode_s core_operation_update_power_mode_c::determine_power_mode() const
+    {
+    DEBUG( "core_operation_update_power_mode_c::determine_power_mode()" );
+
+    if( !server_m->get_device_settings().power_save_enabled )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_CAM, disabled in settings" );
+        
+        return CORE_POWER_MODE_CAM;
+        }
+
+    if ( server_m->get_connection_data() &&
+         server_m->get_connection_data()->iap_data().operating_mode() == core_operating_mode_ibss )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_CAM, IBSS network" );
+
+        return CORE_POWER_MODE_CAM;
+        }
+
+    if( preferred_mode_m.mode == core_power_save_mode_none )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_CAM, preferred mode" );
+
+        return CORE_POWER_MODE_CAM;        
+        }
+
+    if( preferred_mode_m.mode == core_power_save_mode_beacon )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_PS_BEACON, preferred mode" );
+
+        core_power_mode_s mode( CORE_POWER_MODE_PS_BEACON );
+        mode.wakeup_interval_light = preferred_mode_m.wakeup_interval;
+        mode.wakeup_interval_deep = preferred_mode_m.wakeup_interval;
+
+        return mode;
+        }
+
+    if( preferred_mode_m.mode == core_power_save_mode_dtim )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_PS_DTIM, preferred mode" );
+
+        core_power_mode_s mode( CORE_POWER_MODE_PS_DTIM );
+        mode.wakeup_interval_light = preferred_mode_m.wakeup_interval;
+        mode.wakeup_interval_deep = preferred_mode_m.wakeup_interval;
+
+        return mode;
+        }
+
+    u8_t wakeup_interval( 1 );
+    bool_t is_power_save_test_success( true_t );
+    if( server_m->get_connection_data() &&
+        server_m->get_connection_data()->current_ap_data() )
+        {                
+        u32_t dtim_skip_interval(
+            server_m->get_connection_data()->current_ap_data()->dtim_period() *
+            server_m->get_connection_data()->current_ap_data()->beacon_interval() *
+            MILLISECONDS_FROM_MICROSECONDS );
+
+        /**
+         * DTIM period can be zero if we haven't received a beacon from
+         * the AP yet.
+         */        
+        if( dtim_skip_interval )
+            {
+            DEBUG1( "core_operation_update_power_mode_c::determine_power_mode() - max_dtim_skip_interval: %u",
+                server_m->get_device_settings().max_dtim_skip_interval );
+            DEBUG1( "core_operation_update_power_mode_c::determine_power_mode() - dtim_skip_interval: %u",
+                dtim_skip_interval );
+
+            while( dtim_skip_interval * ( wakeup_interval + 1 ) <= server_m->get_device_settings().max_dtim_skip_interval )
+                {
+                ++wakeup_interval;
+                }
+            }
+
+        core_mac_address_s bssid(
+            server_m->get_connection_data()->current_ap_data()->bssid() );
+        server_m->get_connection_data()->is_ap_power_save_test_run(
+            bssid, is_power_save_test_success );
+        }
+
+    if( preferred_mode_m.mode == core_power_save_mode_dtim_skipping )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_PS_DTIM, preferred mode" );
+
+        core_power_mode_s mode( CORE_POWER_MODE_PS_DTIM );
+        mode.wakeup_interval_light = wakeup_interval;
+        mode.wakeup_interval_deep = wakeup_interval;
+
+        return mode;
+        }
+
+    if( !is_power_save_test_success )
+        {
+        DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_CAM, AP power save test failure" );
+
+        return CORE_POWER_MODE_CAM;
+        }
+
+    DEBUG( "core_operation_update_power_mode_c::determine_power_mode() - CORE_POWER_MODE_PS" );
+
+    core_power_mode_s mode( CORE_POWER_MODE_PS );
+    mode.wakeup_interval_deep = wakeup_interval;
+
+    return mode;
+    }