wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_check_rcpi.cpp
changeset 0 c40eb8fe8501
child 10 0abc8c98be24
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2005-2010 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 requesting RCPI values for roaming.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 21 %
       
    20 */
       
    21 
       
    22 #include "core_operation_check_rcpi.h"
       
    23 #include "core_operation_roam.h"
       
    24 #include "core_operation_handle_bss_lost.h"
       
    25 #include "core_sub_operation_roam_scan.h"
       
    26 #include "core_server.h"
       
    27 #include "am_debug.h"
       
    28 
       
    29 // ======== MEMBER FUNCTIONS ========
       
    30 
       
    31 // ---------------------------------------------------------------------------
       
    32 // ---------------------------------------------------------------------------
       
    33 //
       
    34 core_operation_check_rcpi_c::core_operation_check_rcpi_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_rcpi_check_reason_e reason ) :
       
    40     core_operation_base_c( core_operation_check_rcpi, request_id, server, drivers, adaptation,
       
    41         core_base_flag_drivers_needed | core_base_flag_connection_needed | core_base_flag_roam_operation ),
       
    42     reason_m(  reason ),
       
    43     current_rcpi_m( 0 ),
       
    44     is_connected_m( true_t ) 
       
    45     {
       
    46     DEBUG( "core_operation_check_rcpi_c::core_operation_check_rcpi_c()" );
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 core_operation_check_rcpi_c::~core_operation_check_rcpi_c()
       
    53     {
       
    54     DEBUG( "core_operation_check_rcpi_c::~core_operation_check_rcpi_c()" );
       
    55     }
       
    56     
       
    57 // ---------------------------------------------------------------------------
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 core_error_e core_operation_check_rcpi_c::next_state()
       
    61     {
       
    62     DEBUG( "core_operation_check_rcpi_c::next_state()" );
       
    63     
       
    64     switch ( operation_state_m )
       
    65         {
       
    66         case core_state_init:
       
    67             {
       
    68 #ifdef _DEBUG
       
    69             switch ( reason_m )
       
    70                 {
       
    71                 case core_rcpi_check_reason_timer:
       
    72                     DEBUG( "core_operation_check_rcpi_c::next_state() - core_rcpi_check_reason_timer" );
       
    73                     break;
       
    74                 case core_rcpi_check_reason_rcpi_trigger:
       
    75                     DEBUG( "core_operation_check_rcpi_c::next_state() - core_rcpi_check_reason_rcpi_trigger" );
       
    76                     break;
       
    77                 case core_rcpi_check_reason_signal_loss_prediction:
       
    78                     DEBUG( "core_operation_check_rcpi_c::next_state() - core_rcpi_check_reason_signal_loss_prediction" );
       
    79                     break;
       
    80                 default:
       
    81                     ASSERT( false_t );
       
    82                 }
       
    83 #endif // _DEBUG
       
    84 
       
    85             operation_state_m = core_state_rcpi_received;
       
    86 
       
    87             /**
       
    88              * Cancel the roaming timer just in case.
       
    89              */
       
    90             server_m->cancel_roam_timer();
       
    91 
       
    92             DEBUG( "core_operation_check_rcpi_c::next_state() - requesting RCPI" );
       
    93 
       
    94             drivers_m->get_current_rcpi(
       
    95                 request_id_m,
       
    96                 current_rcpi_m );
       
    97 
       
    98             break;
       
    99             }
       
   100         case core_state_rcpi_received:
       
   101             {
       
   102             operation_state_m = core_state_rcpi_trigger;
       
   103 
       
   104             DEBUG1( "core_operation_check_rcpi_c::next_state() - current RCPI is %u",
       
   105                 current_rcpi_m );
       
   106             DEBUG1( "core_operation_check_rcpi_c::next_state() - internal RCPI threshold level is %u",
       
   107                 server_m->get_device_settings().rcpi_trigger );
       
   108             DEBUG1( "core_operation_check_rcpi_c::next_state() - external RCPI threshold level (down) is %u",
       
   109                 server_m->get_core_settings().rcp_decline_boundary() );
       
   110             DEBUG1( "core_operation_check_rcpi_c::next_state() - external RCPI threshold level (up) is %u",
       
   111                 server_m->get_core_settings().rcp_improve_boundary() );
       
   112 
       
   113             u8_t trigger_level_down = server_m->get_core_settings().rcp_decline_boundary();
       
   114             if ( trigger_level_down < server_m->get_device_settings().rcpi_trigger )
       
   115                 {
       
   116                 trigger_level_down = server_m->get_device_settings().rcpi_trigger;
       
   117                 }
       
   118             u8_t trigger_level_up = server_m->get_core_settings().rcp_improve_boundary();
       
   119             if ( trigger_level_up < server_m->get_device_settings().rcpi_trigger )
       
   120                 {
       
   121                 trigger_level_up = server_m->get_device_settings().rcpi_trigger;
       
   122                 }
       
   123 
       
   124             /**
       
   125              * If signal level drops below roaming threshold, attempt roaming.
       
   126              */
       
   127             if ( current_rcpi_m < server_m->get_device_settings().rcpi_trigger &&
       
   128                  server_m->get_connection_data()->iap_data().is_roaming_allowed() )
       
   129                 {
       
   130                 return goto_state( core_state_scan_start );
       
   131                 }
       
   132 
       
   133             /**
       
   134              * If moving from weak level to normal, notify client.
       
   135              */
       
   136             if ( current_rcpi_m > server_m->get_core_settings().rcp_improve_boundary() &&
       
   137                  server_m->get_connection_data()->last_rcp_class() != core_rcp_normal )
       
   138                 {
       
   139                 DEBUG( "core_operation_check_rcpi_c::next_state() - sending a notification about the normal signal level" );
       
   140 
       
   141                 u8_t buf[5];
       
   142                 buf[0] = static_cast<u8_t>( core_rcp_normal );
       
   143                 buf[1] = static_cast<u8_t>( current_rcpi_m );
       
   144 
       
   145                 adaptation_m->notify(
       
   146                     core_notification_rcp_changed,
       
   147                     sizeof( buf ),
       
   148                     buf );
       
   149                 server_m->get_connection_data()->set_last_rcp_class( core_rcp_normal );
       
   150 
       
   151                 DEBUG( "core_operation_check_rcpi_c::next_state() - reseting RCPI roam check interval" );
       
   152                 server_m->get_connection_data()->reset_rcpi_roam_interval();
       
   153                 }
       
   154 
       
   155             /** 
       
   156              * Send an indication to adaptation to indicate that this
       
   157              * roam attempt has been completed.
       
   158              */  
       
   159             adaptation_m->notify(                
       
   160                 core_notification_rcpi_roam_attempt_completed,
       
   161                 0,
       
   162                 NULL );           
       
   163 
       
   164             /**
       
   165              * If the signal level is above the trigger level, we only have to check
       
   166              * whether we should re-arm the trigger.
       
   167              */
       
   168             if ( current_rcpi_m > trigger_level_up )
       
   169                 {
       
   170                 DEBUG1( "core_operation_check_rcpi_c::next_state() - signal level is above trigger_level_up (%u)",
       
   171                     trigger_level_up );
       
   172 
       
   173                 /**
       
   174                  * If the operation was started because of a trigger event, schedule a timer.
       
   175                  * This is done to prevent constant triggering when the signal level is
       
   176                  * hovering right on the trigger level.
       
   177                  */
       
   178                 if ( reason_m == core_rcpi_check_reason_rcpi_trigger ||
       
   179                      reason_m == core_rcpi_check_reason_signal_loss_prediction )
       
   180                     {
       
   181                     DEBUG1( "core_operation_check_rcpi_c::next_state() - was triggered, scheduling the roaming timer to %u",
       
   182                         server_m->get_device_settings().roam_timer );
       
   183 
       
   184                     server_m->schedule_roam_timer(
       
   185                         server_m->get_device_settings().roam_timer );
       
   186 
       
   187                     return core_error_ok;
       
   188                     }
       
   189 
       
   190                 /**
       
   191                  * At least one timer-based poll has been done, trigger can be re-armed.
       
   192                  */
       
   193                 DEBUG1( "core_operation_check_rcpi_c::next_state() - was not triggered, arming RCPI roam trigger (%u)",
       
   194                     trigger_level_down );
       
   195 
       
   196                 drivers_m->set_rcpi_trigger_level(
       
   197                     request_id_m,
       
   198                     trigger_level_down );
       
   199 
       
   200                 DEBUG( "core_operation_check_rcpi_c::next_state() - reseting RCPI roam check interval" );
       
   201                 server_m->get_connection_data()->reset_rcpi_roam_interval();
       
   202 
       
   203                 return core_error_request_pending;
       
   204                 }
       
   205 
       
   206             /**
       
   207              * If we have come this far, it means the current signal level is between the
       
   208              * external and the internal threshold level. Schedule a timer and if the operation
       
   209              * was started because of a timer event, re-arm the trigger as well.
       
   210              */
       
   211             DEBUG2( "core_operation_check_rcpi_c::next_state() - between trigger_level_down (%u) and trigger_level_up (%u)",
       
   212                 trigger_level_down, trigger_level_up );
       
   213             DEBUG1( "core_operation_check_rcpi_c::next_state() - scheduling the roaming timer to %u",
       
   214                 server_m->get_device_settings().roam_timer );
       
   215 
       
   216             server_m->schedule_roam_timer(
       
   217                 server_m->get_device_settings().roam_timer );            
       
   218 
       
   219             if ( reason_m == core_rcpi_check_reason_timer )
       
   220                 {
       
   221                 DEBUG1( "core_operation_check_rcpi_c::next_state() - was not triggered, arming RCPI roam trigger (%u)",
       
   222                     trigger_level_down );                
       
   223 
       
   224                 drivers_m->set_rcpi_trigger_level(
       
   225                     request_id_m,
       
   226                     trigger_level_down );
       
   227 
       
   228                 return core_error_request_pending;
       
   229                 }
       
   230 
       
   231             return core_error_ok;
       
   232             }
       
   233         case core_state_rcpi_trigger:
       
   234             {
       
   235             DEBUG( "core_operation_check_rcpi_c::next_state() - trigger re-armed" ); 
       
   236 
       
   237             return core_error_ok;
       
   238             }
       
   239         case core_state_scan_start:
       
   240             {
       
   241             operation_state_m = core_state_scan_complete;
       
   242 
       
   243             DEBUG( "core_operation_check_rcpi_c::next_state() - starting a direct scan on all channels" );           
       
   244 
       
   245             server_m->get_scan_list().set_tag(
       
   246                 core_scan_list_tag_roam_scan );
       
   247 
       
   248             core_operation_base_c* operation = new core_sub_operation_roam_scan_c(
       
   249                 request_id_m,
       
   250                 server_m,
       
   251                 drivers_m,
       
   252                 adaptation_m,
       
   253                 server_m->get_connection_data()->ssid(),
       
   254                 server_m->get_core_settings().all_valid_scan_channels(),
       
   255                 true_t,
       
   256                 false_t );
       
   257 
       
   258             return run_sub_operation( operation );            
       
   259             }
       
   260         case core_state_scan_complete:
       
   261             {
       
   262             operation_state_m = core_state_connect_success;
       
   263 
       
   264             DEBUG( "core_operation_check_rcpi_c::next_state() - attempting to roam" );
       
   265 
       
   266             if ( reason_m == core_rcpi_check_reason_signal_loss_prediction )
       
   267                 {
       
   268                 server_m->get_connection_data()->set_last_roam_reason(
       
   269                     core_roam_reason_signal_loss_prediction );
       
   270                 }
       
   271             else
       
   272                 {
       
   273                 server_m->get_connection_data()->set_last_roam_reason(
       
   274                     core_roam_reason_signal_strength );               
       
   275                 }
       
   276             server_m->get_connection_data()->set_last_roam_failed_reason(
       
   277                 core_roam_failed_reason_none );
       
   278 
       
   279             medium_time_s admitted_medium_time(
       
   280                 server_m->get_connection_data()->traffic_stream_list().admitted_medium_time() );            
       
   281 
       
   282             core_operation_base_c* operation = new core_operation_roam_c(
       
   283                 request_id_m,
       
   284                 server_m,
       
   285                 drivers_m,
       
   286                 adaptation_m,
       
   287                 is_connected_m,
       
   288                 core_scan_list_tag_roam_scan,
       
   289                 current_rcpi_m + server_m->get_device_settings().rcpi_difference,
       
   290                 admitted_medium_time,
       
   291                 server_m->get_connection_data()->ssid(),
       
   292                 BROADCAST_MAC_ADDR );
       
   293 
       
   294             return run_sub_operation( operation );
       
   295             }                                   
       
   296         case core_state_connect_success:
       
   297             {
       
   298             operation_state_m = core_state_rcpi_trigger;
       
   299 
       
   300             DEBUG( "core_operation_check_rcpi_c::next_state() - roamed successfully" );
       
   301                         
       
   302             /**
       
   303              * If moving from weak level to normal, notify client.
       
   304              */
       
   305             if ( server_m->get_connection_data()->last_rcp_class() != core_rcp_normal )
       
   306                 {
       
   307                 DEBUG( "core_operation_check_rcpi_c::next_state() - sending a notification about the normal signal level" );
       
   308 
       
   309                 u8_t buf[5];
       
   310                 buf[0] = static_cast<u8_t>( core_rcp_normal );
       
   311                 buf[1] = server_m->get_connection_data()->current_ap_data()->rcpi();
       
   312                 
       
   313                 adaptation_m->notify(
       
   314                     core_notification_rcp_changed,
       
   315                     sizeof( buf ),
       
   316                     buf );
       
   317                 server_m->get_connection_data()->set_last_rcp_class( core_rcp_normal );
       
   318                 }
       
   319 
       
   320             /** 
       
   321              * Send an indication to adaptation to indicate that this
       
   322              * roam attempt has been completed.
       
   323              */  
       
   324             adaptation_m->notify(                
       
   325                 core_notification_rcpi_roam_attempt_completed,
       
   326                 0,
       
   327                 NULL );           
       
   328 
       
   329             DEBUG( "core_operation_check_rcpi_c::next_state() - reseting RCPI roam check interval" );
       
   330             server_m->get_connection_data()->reset_rcpi_roam_interval();
       
   331 
       
   332             DEBUG1( "core_operation_check_rcpi_c::next_state() - internal RCPI threshold level is %u",
       
   333                 server_m->get_device_settings().rcpi_trigger );
       
   334             DEBUG1( "core_operation_check_rcpi_c::next_state() - external RCPI threshold level is %u",
       
   335                 server_m->get_core_settings().rcp_decline_boundary() );
       
   336 
       
   337             u8_t trigger_level = server_m->get_core_settings().rcp_decline_boundary();
       
   338             if ( trigger_level < server_m->get_device_settings().rcpi_trigger )
       
   339                 {
       
   340                 trigger_level = server_m->get_device_settings().rcpi_trigger;
       
   341                 }
       
   342             DEBUG1( "core_operation_check_rcpi_c::next_state() - arming RCPI roam trigger (%u)",
       
   343                 trigger_level );
       
   344 
       
   345             drivers_m->set_rcpi_trigger_level(
       
   346                 request_id_m,
       
   347                 trigger_level );
       
   348 
       
   349             break;
       
   350             }
       
   351         case core_state_connect_failure:
       
   352             {
       
   353             operation_state_m = core_state_rcpi_trigger;
       
   354                       
       
   355             DEBUG( "core_operation_check_rcpi_c::next_state() - roaming failed" );
       
   356             
       
   357             DEBUG1( "core_operation_check_rcpi_c::next_state() - internal RCPI threshold level is %u",
       
   358                 server_m->get_device_settings().rcpi_trigger );
       
   359             DEBUG1( "core_operation_check_rcpi_c::next_state() - external RCPI threshold level is %u",
       
   360                 server_m->get_core_settings().rcp_decline_boundary() );
       
   361             
       
   362             DEBUG1( "core_operation_check_rcpi_c::next_state() - current RCPI is %u",
       
   363                 current_rcpi_m );
       
   364 
       
   365             u8_t weak_trigger_level = server_m->get_core_settings().rcp_decline_boundary();
       
   366             if ( weak_trigger_level > server_m->get_device_settings().rcpi_trigger )
       
   367                 {
       
   368                 weak_trigger_level = server_m->get_device_settings().rcpi_trigger;
       
   369                 }
       
   370             weak_trigger_level = weak_trigger_level - 20;
       
   371             
       
   372             DEBUG1( "core_operation_check_rcpi_c::next_state() - weak_trigger_level (%u)",
       
   373                                weak_trigger_level );
       
   374             /**
       
   375              * If we haven't notified the clients about a weak signal earlier,
       
   376              * do it now.
       
   377              */
       
   378             if ( current_rcpi_m < weak_trigger_level &&
       
   379                 server_m->get_connection_data()->last_rcp_class() != core_rcp_weak )
       
   380                 {
       
   381                 DEBUG( "core_operation_check_rcpi_c::next_state() - sending a notification about the weak signal level" );
       
   382 
       
   383                 u8_t buf[5];
       
   384                 buf[0] = static_cast<u8_t>( core_rcp_weak );
       
   385                 buf[1] = static_cast<u8_t>( current_rcpi_m );
       
   386                   
       
   387                 /**
       
   388                  * Get current IAP Id value and add it to the weak list. 
       
   389                  */
       
   390                 server_m->get_core_settings().add_iap_id_to_weak_iap_list(
       
   391                      server_m->get_connection_data()->iap_data().iap_id());
       
   392                  
       
   393                 adaptation_m->notify(
       
   394                     core_notification_rcp_changed,
       
   395                     sizeof( buf ),
       
   396                     buf );
       
   397                 server_m->get_connection_data()->set_last_rcp_class( core_rcp_weak ); 
       
   398                 
       
   399                 }
       
   400 
       
   401             if ( !is_connected_m )
       
   402                 {
       
   403                 DEBUG( "core_operation_check_rcpi_c::next_state() - no longer connected, scheduling bss_lost operation" );
       
   404 
       
   405                 core_operation_base_c* operation = new core_operation_handle_bss_lost_c(
       
   406                     REQUEST_ID_CORE_INTERNAL,
       
   407                     server_m,
       
   408                     drivers_m,
       
   409                     adaptation_m,
       
   410                     core_operation_handle_bss_lost_c::core_bss_lost_reason_failed_rcpi_roam );
       
   411 
       
   412                 server_m->queue_int_operation( operation );
       
   413                 }
       
   414             else
       
   415                 {
       
   416                 /** 
       
   417                  * Send an indication to adaptation to indicate that this
       
   418                  * roam attempt has been completed.
       
   419                  */  
       
   420                 adaptation_m->notify(                
       
   421                     core_notification_rcpi_roam_attempt_completed,
       
   422                     0,
       
   423                     NULL );
       
   424                 
       
   425                 core_rcpi_roam_interval_s interval(
       
   426                     server_m->get_connection_data()->rcpi_roam_interval() );
       
   427                 ++interval.count;
       
   428 
       
   429                 if ( interval.count > server_m->get_device_settings().rcpi_roam_attempts_per_interval )
       
   430                     {
       
   431                     DEBUG1( "core_operation_check_rcpi_c::next_state() - maximum interval attempts (%u) exceeded, increasing interval",
       
   432                         server_m->get_device_settings().rcpi_roam_attempts_per_interval );
       
   433                     interval.count = 1;
       
   434                     interval.interval *= server_m->get_device_settings().rcpi_roam_next_interval_factor;
       
   435                     interval.interval += server_m->get_device_settings().rcpi_roam_next_interval_addition;
       
   436 
       
   437                     if ( interval.interval > server_m->get_device_settings().rcpi_roam_max_interval )
       
   438                         {
       
   439                         interval.interval = server_m->get_device_settings().rcpi_roam_max_interval;
       
   440                         
       
   441                         DEBUG1( "core_operation_check_rcpi_c::next_state() - interval value set to maximum (%u)",
       
   442                             interval.interval );
       
   443                         }
       
   444                     else
       
   445                         {
       
   446                         DEBUG1( "core_operation_check_rcpi_c::next_state() - interval value set to %u",
       
   447                             interval.interval );
       
   448                         }
       
   449                     }
       
   450 
       
   451                 server_m->get_connection_data()->set_core_rcpi_roam_interval(
       
   452                     interval );
       
   453 
       
   454                 DEBUG1( "core_operation_check_rcpi_c::next_state() - arming the roaming timer to %u",
       
   455                     interval.interval );
       
   456 
       
   457                 server_m->schedule_roam_timer(
       
   458                     interval.interval );
       
   459                 
       
   460                 if ( server_m->get_connection_data()->last_rcp_class() != core_rcp_weak )
       
   461                     {
       
   462                     DEBUG( "core_operation_check_rcpi_c::next_state() - set_rcpi_trigger_level( weak_trigger_level )" );
       
   463             
       
   464                     DEBUG1( "core_operation_check_rcpi_c::next_state() - arming new RCPI roam trigger (%u)",
       
   465                         weak_trigger_level );
       
   466                
       
   467                     drivers_m->set_rcpi_trigger_level(   
       
   468                          request_id_m,
       
   469                          weak_trigger_level );
       
   470                
       
   471                     return core_error_request_pending;
       
   472                     }
       
   473                 }
       
   474             return core_error_ok;
       
   475             }
       
   476         default:
       
   477             {
       
   478             ASSERT( false_t );
       
   479             }
       
   480         }
       
   481 
       
   482     return core_error_request_pending;
       
   483     }
       
   484 
       
   485 // ---------------------------------------------------------------------------
       
   486 // ---------------------------------------------------------------------------
       
   487 //
       
   488 core_error_e core_operation_check_rcpi_c::cancel()
       
   489     {
       
   490     DEBUG( "core_operation_check_rcpi_c::cancel() " );    
       
   491     
       
   492     switch ( operation_state_m )
       
   493         {              
       
   494         case core_state_connect_success:
       
   495             {            
       
   496             return goto_state( core_state_connect_failure );
       
   497             }
       
   498         default:
       
   499             {
       
   500             /** 
       
   501              * Send an indication to adaptation to indicate that this
       
   502              * roam attempt has been completed.
       
   503              */  
       
   504             adaptation_m->notify(                
       
   505                 core_notification_rcpi_roam_attempt_completed,
       
   506                 0,
       
   507                 NULL );
       
   508 
       
   509             return failure_reason_m;
       
   510             }
       
   511         }    
       
   512     }