wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_power_save_test.cpp
changeset 0 c40eb8fe8501
child 5 51a71243e562
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Statemachine for running an echo test in power save.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "core_operation_power_save_test.h"
       
    20 #include "core_operation_update_power_mode.h"
       
    21 #include "core_sub_operation_echo_test.h"
       
    22 #include "core_tools.h"
       
    23 #include "core_server.h"
       
    24 #include "am_debug.h"
       
    25 
       
    26 /** The maximum amount of times a particular echo frame is re-sent. */
       
    27 const u8_t CORE_MAX_POWER_SAVE_TEST_RETRY_COUNT = 3;
       
    28 
       
    29 // ======== MEMBER FUNCTIONS ========
       
    30 
       
    31 // ---------------------------------------------------------------------------
       
    32 // ---------------------------------------------------------------------------
       
    33 //
       
    34 core_operation_power_save_test_c::core_operation_power_save_test_c(
       
    35     u32_t request_id,
       
    36     core_server_c* server,
       
    37     abs_core_driverif_c* drivers,
       
    38     abs_core_server_callback_c* adaptation ) :
       
    39     core_operation_base_c( core_operation_power_save_test, request_id, server, drivers, adaptation,
       
    40         core_base_flag_connection_needed | core_base_flag_only_one_instance ),
       
    41     current_ap_m( NULL ),
       
    42     return_status_m( core_error_ok ),
       
    43     is_power_save_m( true_t ),
       
    44     is_unicast_test_on_m( true_t )
       
    45     {
       
    46     DEBUG( "core_operation_power_save_test_c::core_operation_power_save_test_c()" );
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 core_operation_power_save_test_c::~core_operation_power_save_test_c()
       
    53     {
       
    54     DEBUG( "core_operation_power_save_test_c::~core_operation_power_save_test_c()" );
       
    55 
       
    56     current_ap_m = NULL;
       
    57     }
       
    58     
       
    59 // ---------------------------------------------------------------------------
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 core_error_e core_operation_power_save_test_c::next_state()
       
    63     {
       
    64     DEBUG( "core_operation_power_save_test_c::next_state()" );
       
    65     
       
    66     switch ( operation_state_m )
       
    67         {
       
    68         case core_state_init:
       
    69             {
       
    70             DEBUG( "core_operation_power_save_test_c::next_state() core_state_init" );
       
    71             if( !server_m->get_core_settings().is_driver_loaded() ||
       
    72                  !server_m->get_connection_data() ||
       
    73                  !server_m->get_connection_data()->current_ap_data() )
       
    74                 {
       
    75                 DEBUG( "core_operation_power_save_test_c::next_state() - not connected, no reason to run the power save test" );
       
    76 
       
    77                 return core_error_not_supported;
       
    78                 }
       
    79 
       
    80             current_ap_m = server_m->get_connection_data()->current_ap_data();
       
    81             core_mac_address_s bssid(
       
    82                 current_ap_m->bssid() );
       
    83 
       
    84             /**
       
    85              * If this AP has already been tested, do not test it again.
       
    86              */
       
    87             bool_t is_success( true_t );
       
    88             if( server_m->get_connection_data()->is_ap_power_save_test_run(
       
    89                 bssid,
       
    90                 is_success ) )
       
    91                 {
       
    92                 DEBUG1( "core_operation_power_save_test_c::next_state() - AP already tested (verdict %u)",
       
    93                     is_success );
       
    94 
       
    95                 return core_error_ok;
       
    96                 }
       
    97 
       
    98             /**
       
    99              * If the feature isn't enabled, pretend the test succeeded.
       
   100              */
       
   101             if( !server_m->get_core_settings().is_feature_enabled(
       
   102                 core_feature_power_save_test ) )
       
   103                 {
       
   104                 return goto_state( core_state_reset_power_mode );
       
   105                 }
       
   106 
       
   107             /**
       
   108              * Set the phone to wake up on every DTIM.
       
   109              */
       
   110             core_operation_base_c* operation = new core_operation_update_power_mode_c(
       
   111                 request_id_m,
       
   112                 server_m,
       
   113                 drivers_m,
       
   114                 adaptation_m,
       
   115                 CORE_POWER_SAVE_MODE_EVERY_DTIM );
       
   116 
       
   117             return run_sub_operation( operation, core_state_echo_test );
       
   118             }
       
   119         case core_state_set_power_mode_none:
       
   120             {
       
   121             DEBUG( "core_operation_power_save_test_c::next_state(): core_state_set_power_mode_none" );
       
   122             is_power_save_m = false_t;
       
   123             return_status_m = core_error_ok;
       
   124 
       
   125             /**
       
   126              * Disable power save.
       
   127              */
       
   128             core_operation_base_c* operation = new core_operation_update_power_mode_c(
       
   129                 request_id_m,
       
   130                 server_m,
       
   131                 drivers_m,
       
   132                 adaptation_m,
       
   133                 CORE_POWER_SAVE_MODE_NONE );
       
   134 
       
   135             return run_sub_operation( operation, core_state_echo_test );            
       
   136             }
       
   137         case core_state_set_power_mode_on:
       
   138             {
       
   139             is_power_save_m = true_t;
       
   140             return_status_m = core_error_ok;
       
   141 
       
   142             /**
       
   143              * Set the phone to wake up on every DTIM.
       
   144              */
       
   145             core_operation_base_c* operation = new core_operation_update_power_mode_c(
       
   146                 request_id_m,
       
   147                 server_m,
       
   148                 drivers_m,
       
   149                 adaptation_m,
       
   150                 CORE_POWER_SAVE_MODE_EVERY_DTIM );
       
   151             
       
   152             DEBUG( "core_operation_power_save_test_c::next_state(): core_state_set_power_mode_on" );
       
   153             is_unicast_test_on_m = false_t;
       
   154 
       
   155             return run_sub_operation( operation, core_state_echo_test );            
       
   156             }
       
   157         case core_state_echo_test:
       
   158             {
       
   159             /**
       
   160              * The phone is now in correct power mode and the echo test can be started.
       
   161              */
       
   162 
       
   163             /**
       
   164              * The response timeout is based on the AP's beacon interval and DTIM period.
       
   165              */
       
   166             u32_t timeout = ( current_ap_m->beacon_interval() * current_ap_m->dtim_period() + 20 ) *
       
   167                 MILLISECONDS_FROM_MICROSECONDS;
       
   168             DEBUG3( "core_operation_power_save_test_c::next_state() - AP beacon interval is %u ms, DTIM period is %u, timeout is %u us",
       
   169                 current_ap_m->beacon_interval(),
       
   170                 current_ap_m->dtim_period(),
       
   171                 timeout );
       
   172  
       
   173             
       
   174             core_operation_base_c* operation = new core_sub_operation_echo_test_c(
       
   175                     request_id_m,
       
   176                     server_m,
       
   177                     drivers_m,
       
   178                     adaptation_m,
       
   179                     *current_ap_m,
       
   180                     CORE_MAX_POWER_SAVE_TEST_RETRY_COUNT,
       
   181                     timeout,
       
   182                     is_unicast_test_on_m );
       
   183 
       
   184             return run_sub_operation( operation, core_state_echo_test_complete );
       
   185             }
       
   186         case core_state_echo_test_complete:
       
   187             {
       
   188             DEBUG( "core_operation_power_save_test_c::next_state(): core_state_echo_test_complete" );
       
   189             /**
       
   190              * Echo test has been completed.
       
   191              */
       
   192 
       
   193             /**
       
   194              * Echo test can fail because the AP just refuses to echo unicast or
       
   195              * broadcast frames. Re-run the test without power save.
       
   196              */
       
   197             if( is_power_save_m &&
       
   198                 return_status_m == core_error_timeout )
       
   199                 {
       
   200                 return goto_state( core_state_set_power_mode_none ); //first & third
       
   201                 }
       
   202             
       
   203             if( is_unicast_test_on_m &&
       
   204                 return_status_m == core_error_timeout )
       
   205                 {
       
   206                 return goto_state( core_state_set_power_mode_on ); //second
       
   207                 }
       
   208                 
       
   209             return goto_state( core_state_reset_power_mode ); //fourth (or any if success)
       
   210             }
       
   211         case core_state_reset_power_mode:
       
   212             {
       
   213             core_mac_address_s bssid(
       
   214                 current_ap_m->bssid() );
       
   215 
       
   216             if( is_power_save_m &&
       
   217                 return_status_m == core_error_ok )
       
   218                 {
       
   219                 /**
       
   220                  * Echo test w/ power save was completed successfully. 
       
   221                  */
       
   222                 DEBUG( "core_operation_power_save_test_c::next_state() - power save test verdict: PASS" );
       
   223 
       
   224                 server_m->get_connection_data()->add_ap_power_save_test_verdict(
       
   225                     bssid,
       
   226                     true_t );
       
   227                 }
       
   228             else if( return_status_m == core_error_ok )
       
   229                 {
       
   230                 /**
       
   231                  * Echo test w/ power save failed but succeeded without power save.
       
   232                  */
       
   233                 DEBUG( "core_operation_power_save_test_c::next_state() - power save test verdict: FAIL" );
       
   234 
       
   235                 server_m->get_connection_data()->add_ap_power_save_test_verdict(
       
   236                     bssid,
       
   237                     false_t );                
       
   238                 /**
       
   239                  * Notify adaptation about the failed test.
       
   240                  */
       
   241                 adaptation_m->notify(
       
   242                     core_notification_broken_power_save_test_failed,
       
   243                     0,
       
   244                     NULL );
       
   245                 }
       
   246             else if( return_status_m == core_error_timeout )
       
   247                 {
       
   248                 /**
       
   249                  * Echo test failed both without and with power save.
       
   250                  */
       
   251                 DEBUG( "core_operation_power_save_test_c::next_state() - power save test verdict: INCONCLUSIVE" );
       
   252 
       
   253                 server_m->get_connection_data()->add_ap_power_save_test_verdict(
       
   254                     bssid,
       
   255                     true_t );                
       
   256                 }
       
   257             else
       
   258                 {
       
   259                 DEBUG1( "core_operation_power_save_test_c::next_state() - power save test verdict: UNKNOWN (failure %u)",
       
   260                     return_status_m );
       
   261                 }
       
   262 
       
   263             DEBUG( "core_operation_power_save_test_c::next_state() - scheduling a power save update" );
       
   264 
       
   265             core_operation_base_c* operation = new core_operation_update_power_mode_c(
       
   266                 REQUEST_ID_CORE_INTERNAL,
       
   267                 server_m,
       
   268                 drivers_m,
       
   269                 adaptation_m );
       
   270 
       
   271             server_m->queue_int_operation( operation );
       
   272 
       
   273             return return_status_m;
       
   274             }            
       
   275         default:
       
   276             {
       
   277             ASSERT( false_t );
       
   278             }
       
   279         }
       
   280 
       
   281     return core_error_request_pending;
       
   282     }
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // ---------------------------------------------------------------------------
       
   286 //
       
   287 core_error_e core_operation_power_save_test_c::cancel()
       
   288     {
       
   289     DEBUG( "core_operation_power_save_test_c::cancel() " );    
       
   290 
       
   291     switch ( operation_state_m )
       
   292         {
       
   293         case core_state_echo_test_complete:
       
   294             {
       
   295             // Store the return status of the echo test operation.
       
   296             return_status_m = failure_reason_m;
       
   297 
       
   298             return next_state();
       
   299             }
       
   300         default:
       
   301             {
       
   302             return failure_reason_m;
       
   303             }
       
   304         }
       
   305     }