wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_update_power_mode.cpp
--- /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;
+ }