wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_get_available_iaps.cpp
changeset 0 c40eb8fe8501
child 6 e0f767079796
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:  State machine for IAP availability.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 40.1.2 %
       
    20 */
       
    21 
       
    22 #include "core_operation_get_available_iaps.h"
       
    23 #include "core_server.h"
       
    24 #include "core_tools.h"
       
    25 #include "core_tools_parser.h"
       
    26 #include "core_frame_dot11.h"
       
    27 #include "core_frame_dot11_ie.h"
       
    28 #include "am_debug.h"
       
    29 
       
    30 /** Defining this enables IAP related traces. */
       
    31 //#define WLAN_CORE_DEEP_DEBUG 1
       
    32 
       
    33 /** The channel time used in the long passive scan. */
       
    34 const u32_t LONG_PASSIVE_SCAN_CHANNEL_TIME = 210;
       
    35 
       
    36 /**
       
    37  * If the phone has at least this many IAPs marked as hidden,
       
    38  * limiting algorithm will be used for detecting available IAPs.
       
    39  */
       
    40 const u8_t MIN_HIDDEN_IAPS_FOR_LIMITING_ALGORITHM = 15;
       
    41 
       
    42 // ======== MEMBER FUNCTIONS ========
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 core_operation_get_available_iaps_c::core_operation_get_available_iaps_c(
       
    48     u32_t request_id,
       
    49     core_server_c* server,        
       
    50     abs_core_driverif_c* drivers,
       
    51     abs_core_server_callback_c* adaptation,
       
    52     bool_t is_active_scan_allowed,
       
    53     core_type_list_c<core_iap_data_s>& iap_data_list,
       
    54     core_type_list_c<u32_t>& iap_id_list,
       
    55     core_type_list_c<core_ssid_entry_s>* iap_ssid_list,
       
    56     ScanList& scan_data ) :
       
    57     core_operation_base_c( core_operation_get_available_iaps, request_id, server, drivers, adaptation,
       
    58         core_base_flag_drivers_needed ),    
       
    59     is_active_scan_allowed_m( is_active_scan_allowed ),
       
    60     is_limiting_algorithm_used_m( false_t ),
       
    61     iap_data_list_m( iap_data_list ),
       
    62     iap_id_list_m( iap_id_list ),
       
    63     iap_ssid_list_m( iap_ssid_list ),
       
    64     client_scan_data_m( scan_data ),
       
    65     active_channels_m( ),
       
    66     broadcast_channels_m( ),
       
    67     long_broadcast_count_m( 0 ),
       
    68     non_found_iaps_list_m( ),
       
    69     is_split_scan_m( false_t ),
       
    70     bss_count_m( 0 ),
       
    71     direct_scanned_ssid_m( ),
       
    72     region_from_ap_m( core_wlan_region_fcc )
       
    73     {
       
    74     DEBUG( "core_operation_get_available_iaps_c::core_operation_get_available_iaps_c()" );
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------------------------
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 core_operation_get_available_iaps_c::~core_operation_get_available_iaps_c()
       
    81     {
       
    82     DEBUG( "core_operation_get_available_iaps_c::~core_operation_get_available_iaps_c()" );
       
    83 
       
    84     server_m->unregister_event_handler( this );
       
    85     server_m->unregister_frame_handler( this );
       
    86     non_found_iaps_list_m.clear();
       
    87     iap_ssid_list_m = NULL;
       
    88     }
       
    89 
       
    90 // ---------------------------------------------------------------------------
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 core_error_e core_operation_get_available_iaps_c::next_state()
       
    94     {
       
    95     DEBUG( "core_operation_get_available_iaps_c::next_state()" );
       
    96 
       
    97     switch ( operation_state_m )
       
    98         {
       
    99         case core_state_init:
       
   100             {
       
   101             operation_state_m = core_state_long_broadcast_scan_start;
       
   102 
       
   103 #ifdef WLAN_CORE_DEEP_DEBUG
       
   104             DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP data list:" );
       
   105 
       
   106             core_iap_data_s* iter_data = iap_data_list_m.first();            
       
   107             while( iter_data )
       
   108                 {
       
   109                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - ID: %u",
       
   110                     iter_data->id );
       
   111                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   112                     iter_data->ssid.length, iter_data->ssid.ssid );
       
   113 
       
   114                 iter_data = iap_data_list_m.next();
       
   115                 }
       
   116 
       
   117             if ( iap_ssid_list_m )
       
   118                 {
       
   119                 DEBUG( "core_operation_get_available_iaps_c::next_state()" );
       
   120                 DEBUG( "core_operation_get_available_iaps_c::next_state() - Secondary SSID list:" );
       
   121 
       
   122                 core_ssid_entry_s* iter_entry = iap_ssid_list_m->first();
       
   123                 while( iter_entry )
       
   124                     {
       
   125                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - ID: %u",
       
   126                         iter_entry->id );
       
   127                     DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   128                         iter_entry->ssid.length, iter_entry->ssid.ssid );
       
   129                     DEBUG1S( "core_operation_get_available_iaps_c::next_state() - Used SSID: ",
       
   130                         iter_entry->used_ssid.length, iter_entry->used_ssid.ssid );
       
   131 
       
   132                     iter_entry = iap_ssid_list_m->next();
       
   133                     }
       
   134                 DEBUG( "core_operation_get_available_iaps_c::next_state()" );
       
   135                 }
       
   136 #endif // WLAN_CORE_DEEP_DEBUG
       
   137 
       
   138             server_m->get_scan_list().remove_entries_by_age(
       
   139                 server_m->get_device_settings().scan_list_expiration_time );
       
   140 
       
   141             server_m->get_scan_list().set_tag(
       
   142                 core_scan_list_tag_scan );
       
   143 
       
   144             if ( server_m->get_core_settings().is_connected() )
       
   145                 {
       
   146                 is_split_scan_m = true_t;
       
   147                 DEBUG( "core_operation_get_available_iaps_c::next_state() - using a split-scan" );
       
   148                 }
       
   149             else
       
   150                 {
       
   151                 DEBUG( "core_operation_get_available_iaps_c::next_state() - using a regular scan" );
       
   152                 }
       
   153 
       
   154             /**
       
   155              * Limiting algorithm is only used when there's a certain amount of IAPs
       
   156              * marked as hidden.
       
   157              */
       
   158             if ( hidden_iap_count( iap_data_list_m ) >= MIN_HIDDEN_IAPS_FOR_LIMITING_ALGORITHM )
       
   159                 {
       
   160                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u hidden IAPs defined, using limiting algorithm",
       
   161                     hidden_iap_count( iap_data_list_m ) );
       
   162 
       
   163                 is_limiting_algorithm_used_m = true_t;
       
   164                 }
       
   165 
       
   166             /**
       
   167              * Construct a channel mask of channels that have previously contained
       
   168              * APs with long beacon intervals.
       
   169              */
       
   170             core_long_beacon_interval_channels_s& long_beacon_interval_channels(
       
   171                 server_m->get_core_settings().long_beacon_interval_channels() );
       
   172 
       
   173             for ( u8_t idx( 0 ); idx < SCAN_BAND_2DOT4GHZ_MAX_CHANNEL_EURO; ++idx )
       
   174                 {
       
   175                 if ( long_beacon_interval_channels.channel_scan_count[idx] )
       
   176                     {
       
   177                     long_beacon_interval_channels.channel_scan_count[idx]--;
       
   178                     const u8_t channel( idx + 1);
       
   179 
       
   180                     if ( server_m->get_core_settings().mcc_known() )
       
   181                     	{
       
   182                     	if ( server_m->get_core_settings().is_valid_channel(
       
   183                             SCAN_BAND_2DOT4GHZ,
       
   184                             channel ) )
       
   185                             {
       
   186                             long_broadcast_count_m++;
       
   187 
       
   188                             broadcast_channels_m.add(
       
   189                                 SCAN_BAND_2DOT4GHZ,
       
   190                                 channel );
       
   191                             }
       
   192                     	}
       
   193                     else
       
   194                     	{
       
   195                     	long_broadcast_count_m++;
       
   196                     	broadcast_channels_m.add(
       
   197                                 SCAN_BAND_2DOT4GHZ,
       
   198                                 channel );
       
   199                         }
       
   200                     }
       
   201                 }
       
   202 
       
   203             /**
       
   204              * If we can active scan or the channel mask is empty, we can jump
       
   205              * directly to the main broadcast scan.             
       
   206              */
       
   207             if ( is_active_scan_allowed_m ||
       
   208                  !long_broadcast_count_m )
       
   209                 {
       
   210                 long_broadcast_count_m = 0;
       
   211 
       
   212                 return goto_state( core_state_long_broadcast_scan_done );
       
   213                 }
       
   214 
       
   215             const core_scan_channels_s channels(
       
   216                 broadcast_channels_m.channels() );
       
   217 
       
   218             DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting long passive broadcast scan on channels 0x%02X%02X",
       
   219                 channels.channels2dot4ghz[1],
       
   220                 channels.channels2dot4ghz[0] );
       
   221 
       
   222             server_m->register_event_handler( this );
       
   223             server_m->register_frame_handler( this );
       
   224 
       
   225             drivers_m->scan(
       
   226                 request_id_m,
       
   227                 core_scan_mode_passive,
       
   228                 BROADCAST_SSID,
       
   229                 server_m->get_device_settings().scan_rate,
       
   230                 channels,
       
   231                 LONG_PASSIVE_SCAN_CHANNEL_TIME,
       
   232                 LONG_PASSIVE_SCAN_CHANNEL_TIME,
       
   233                 is_split_scan_m );
       
   234 
       
   235             break;
       
   236             }
       
   237         case core_state_long_broadcast_scan_start:
       
   238             {
       
   239             DEBUG( "core_operation_get_available_iaps_c::next_state() - long broadcast scan request completed, waiting for scan completion" );
       
   240 
       
   241             break;
       
   242             }
       
   243         case core_state_long_broadcast_scan_done:
       
   244             {
       
   245             operation_state_m = core_state_broadcast_scan_start;
       
   246 
       
   247             if ( !long_broadcast_count_m )
       
   248                 {
       
   249                 broadcast_channels_m.set(
       
   250                     server_m->get_core_settings().all_valid_scan_channels() );
       
   251                 }
       
   252             else
       
   253                 {
       
   254                 broadcast_channels_m.invert_channels();
       
   255                 }
       
   256 
       
   257             const core_scan_channels_s channels(
       
   258                 server_m->get_core_settings().valid_scan_channels( broadcast_channels_m.channels() ) );
       
   259 
       
   260 
       
   261             if ( !is_active_scan_allowed_m ||
       
   262                  is_limiting_algorithm_used_m )
       
   263                 {
       
   264                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting passive broadcast scan on channels 0x%02X%02X",
       
   265                     channels.channels2dot4ghz[1],
       
   266                     channels.channels2dot4ghz[0] );
       
   267 
       
   268                 server_m->register_event_handler( this );
       
   269                 server_m->register_frame_handler( this );
       
   270 
       
   271                 drivers_m->scan(
       
   272                     request_id_m,
       
   273                     core_scan_mode_passive,
       
   274                     BROADCAST_SSID,
       
   275                     server_m->get_device_settings().scan_rate,
       
   276                     channels,
       
   277                     server_m->get_device_settings().passive_scan_min_ch_time,
       
   278                     server_m->get_device_settings().passive_scan_max_ch_time,
       
   279                     is_split_scan_m );
       
   280                 }
       
   281             else
       
   282                 {
       
   283                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting active broadcast scan on channels 0x%02X%02X",
       
   284                     channels.channels2dot4ghz[1],
       
   285                     channels.channels2dot4ghz[0] );
       
   286 
       
   287                 server_m->register_event_handler( this );
       
   288                 server_m->register_frame_handler( this );
       
   289 
       
   290                 drivers_m->scan(
       
   291                     request_id_m,
       
   292                     core_scan_mode_active,
       
   293                     BROADCAST_SSID,
       
   294                     server_m->get_device_settings().scan_rate,
       
   295                     channels,
       
   296                     server_m->get_device_settings().active_scan_min_ch_time,
       
   297                     server_m->get_device_settings().active_scan_max_ch_time,
       
   298                     is_split_scan_m );
       
   299                 }
       
   300 
       
   301             break;
       
   302             }
       
   303         case core_state_broadcast_scan_start:
       
   304             {
       
   305             DEBUG( "core_operation_get_available_iaps_c::next_state() - broadcast scan request completed, waiting for scan completion" );
       
   306 
       
   307             break;            
       
   308             }
       
   309         case core_state_broadcast_scan_done:
       
   310             {            
       
   311             if ( server_m->get_core_settings().mcc_known() )
       
   312             	{
       
   313             	/* When WLAN region is known, the allowed scan channels are known and 
       
   314             	 * handled already */
       
   315             	return goto_state( core_state_broadcast_scan_done_handle_result );
       
   316             	}
       
   317             
       
   318             operation_state_m = core_state_broadcast_scan_start_unknown_region;
       
   319 
       
   320             broadcast_channels_m.set(
       
   321                     server_m->get_core_settings().all_valid_scan_channels() );
       
   322             
       
   323             const core_scan_channels_s channels(
       
   324                     server_m->get_core_settings().invalid_scan_channels( broadcast_channels_m.channels() ) );
       
   325 
       
   326             server_m->register_event_handler( this );
       
   327             server_m->register_frame_handler( this );
       
   328 
       
   329             drivers_m->scan(
       
   330                     request_id_m,
       
   331                     core_scan_mode_passive,
       
   332                     BROADCAST_SSID,
       
   333                     server_m->get_device_settings().scan_rate,
       
   334                     channels,
       
   335                     server_m->get_device_settings().passive_scan_min_ch_time,
       
   336                     server_m->get_device_settings().passive_scan_max_ch_time,
       
   337                     is_split_scan_m );
       
   338             
       
   339             break;
       
   340             }
       
   341         case core_state_broadcast_scan_start_unknown_region:
       
   342         	{
       
   343             DEBUG( "core_operation_get_available_iaps_c::next_state() - broadcast scan request for channels 12 and 13 completed, waiting for scan completion" );
       
   344 
       
   345         	break;
       
   346         	}
       
   347         case core_state_broadcast_scan_complete_unknown_region:
       
   348         	{
       
   349             operation_state_m = core_state_store_country_info;
       
   350 
       
   351             /* If WLAN region was not known before the scan, then check if country information is present
       
   352              * in the scan results. APs on channels 12 and 13 must be ignored if country information indicates this. 
       
   353              */
       
   354             core_scan_list_iterator_by_tag_c iter_country_beacon(
       
   355                 server_m->get_scan_list(),
       
   356                 core_scan_list_tag_scan );
       
   357 
       
   358             core_wlan_region_e found_region = core_wlan_region_undefined;
       
   359             bool_t inconsistent_info( false_t );
       
   360             for ( core_ap_data_c* ap_data = iter_country_beacon.first(); ap_data; ap_data = iter_country_beacon.next() )
       
   361                 {
       
   362                 core_country_string_s country_info = ap_data->country_info();
       
   363                 core_wlan_region_e ap_region = core_wlan_region_undefined;
       
   364                 if ( country_info.country[0] != 0 )                   
       
   365                     {
       
   366                     ap_region = core_tools_c::convert_country_to_region( country_info );
       
   367                     if ( found_region != core_wlan_region_undefined )
       
   368                        	{
       
   369                        	if ( ap_region != found_region )
       
   370                        		{
       
   371                        	    inconsistent_info = true_t; 
       
   372                        		}
       
   373                        	}
       
   374                     else
       
   375                        	{
       
   376                        	found_region = ap_region;
       
   377                        	}                        
       
   378                     }
       
   379                 }
       
   380             if ( found_region != core_wlan_region_undefined )
       
   381                	{
       
   382                	if ( !inconsistent_info )
       
   383                		{	
       
   384                	    region_from_ap_m = found_region;
       
   385                		}
       
   386                	else
       
   387                		{
       
   388                		region_from_ap_m = core_wlan_region_etsi;
       
   389                		}
       
   390                	adaptation_m->store_ap_country_info( request_id_m, region_from_ap_m, inconsistent_info );
       
   391                	}
       
   392             else
       
   393                	{
       
   394                	return goto_state( core_state_broadcast_scan_done_handle_result );
       
   395                	}
       
   396         	break;
       
   397         	}
       
   398         case core_state_store_country_info:
       
   399           	{
       
   400             operation_state_m = core_state_broadcast_scan_done_handle_result;
       
   401             	
       
   402             /* Set the new region information also to core settings */
       
   403             DEBUG1( "core_operation_get_available_iaps_c::next_state() - current region %u",
       
   404                 region_from_ap_m );
       
   405             server_m->get_core_settings().set_regional_domain(
       
   406                 region_from_ap_m );
       
   407             server_m->get_core_settings().set_mcc_known( true_t );
       
   408             	
       
   409             return goto_state( core_state_broadcast_scan_done_handle_result );
       
   410             }
       
   411 
       
   412         case core_state_broadcast_scan_done_handle_result:
       
   413         	{
       
   414         	operation_state_m = core_state_direct_scan_start;
       
   415         	/* If region information is not known, channels 12 and 13 are now been scanned in passive mode in any case */
       
   416 
       
   417         	/* If region is FCC, then ignore and remove the APs from channels 12 and 13 */
       
   418             if ( server_m->get_core_settings().regional_domain() == core_wlan_region_fcc )
       
   419             	{
       
   420             	DEBUG( "core_operation_get_available_iaps_c::next_state() - remove APs that were found on channels 12 and 13" );
       
   421             	remove_disallowed_aps();            	
       
   422             	}
       
   423             
       
   424             /* If WLAN regional domain is not ETSI, we have to remove the high channels from
       
   425              * from the active channels mask to prevent direct scans on those channels.
       
   426              */
       
   427             if ( server_m->get_core_settings().regional_domain() != core_wlan_region_etsi )
       
   428             	{
       
   429                 for ( u8_t idx( SCAN_BAND_2DOT4GHZ_MAX_CHANNEL_FCC ); idx < SCAN_BAND_2DOT4GHZ_MAX_CHANNEL_EURO; ++idx )
       
   430                     {
       
   431                     const u8_t channel( idx + 1);
       
   432                     if ( !server_m->get_core_settings().is_valid_channel(
       
   433                          SCAN_BAND_2DOT4GHZ,
       
   434                          channel ) )
       
   435                         {
       
   436                         active_channels_m.remove(
       
   437                             SCAN_BAND_2DOT4GHZ,
       
   438                             channel );
       
   439                         }
       
   440                     }
       
   441             	}
       
   442 
       
   443             DEBUG1( "core_operation_get_available_iaps_c::next_state() - broadcast scan done, %u beacon(s)/probe(s) received",
       
   444                 bss_count_m );
       
   445 
       
   446             /**
       
   447              * Add the results from the broadcast scan to the scan list so that
       
   448              * they can be cached in adaptation.
       
   449              */
       
   450             core_scan_list_iterator_by_tag_c iter(
       
   451                 server_m->get_scan_list(),
       
   452                 core_scan_list_tag_scan );
       
   453             for ( core_ap_data_c* ap_data = iter.first(); ap_data; ap_data = iter.next() )
       
   454                 {
       
   455                 const core_mac_address_s bssid = ap_data->bssid();
       
   456 
       
   457                 if ( !server_m->get_core_settings().is_mac_in_permanent_blacklist( bssid ) )
       
   458                     {
       
   459                     core_tools_c::add_beacon_to_scan_list(
       
   460                         client_scan_data_m,
       
   461                         *ap_data,
       
   462                         ap_data->rcpi() );
       
   463                     }
       
   464                 }
       
   465 
       
   466             /**
       
   467              * Go through the broadcast scan results and remove matching IAPs.
       
   468              */
       
   469             process_scan_results(
       
   470                 core_scan_list_tag_scan );
       
   471 
       
   472             /**
       
   473              * Direct scans are only needed if active scanning is allowed. If limiting algorithm
       
   474              * is used, channel activity based on broadcast scan is also required.
       
   475              */
       
   476             if ( ( is_active_scan_allowed_m &&
       
   477                    !is_limiting_algorithm_used_m ) ||
       
   478                  ( is_active_scan_allowed_m &&
       
   479                    is_limiting_algorithm_used_m &&
       
   480                    bss_count_m ) )
       
   481                 {
       
   482                 remove_non_hidden_iaps();
       
   483 
       
   484                 /**
       
   485                  * If limiting algorithm is used, only the current active_channels_m
       
   486                  * will be used.
       
   487                  */               
       
   488                 if ( is_limiting_algorithm_used_m )
       
   489                     {
       
   490                     DEBUG( "core_operation_get_available_iaps_c::next_state() - limiting channels based on WLAN activity" );
       
   491                     }
       
   492                 else
       
   493                     {
       
   494                     active_channels_m.set(
       
   495                         server_m->get_core_settings().all_valid_scan_channels() );
       
   496                     }
       
   497 
       
   498                 /**
       
   499                  * iap_data_list_m now contains only hidden ssid IAPs,
       
   500                  * that will be direct scanned next.
       
   501                  */
       
   502                 core_iap_data_s* iap = iap_data_list_m.first();
       
   503                 if( !iap )
       
   504                     {
       
   505                     DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
       
   506 
       
   507                     /** No hidden IAP entries in the request, move on.. */
       
   508                     return goto_state( core_state_secondary_ssid_check );
       
   509                     }
       
   510 
       
   511                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - going to direct scan %u IAP(s)",
       
   512                     iap_data_list_m.count() );
       
   513 
       
   514                 direct_scanned_ssid_m = iap->ssid;
       
   515                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scanning IAP ID %u",
       
   516                     iap->id );
       
   517                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   518                     direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   519 
       
   520                 server_m->get_scan_list().set_tag(
       
   521                     core_scan_list_tag_direct_scan );
       
   522 
       
   523                 const core_scan_channels_s& channels(
       
   524                     active_channels_m.channels() );
       
   525                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting scan on channels 0x%02X%02X",
       
   526                     channels.channels2dot4ghz[1],
       
   527                     channels.channels2dot4ghz[0] );
       
   528 
       
   529                 bss_count_m = 0;
       
   530 
       
   531                 server_m->register_event_handler( this );
       
   532                 server_m->register_frame_handler( this );
       
   533 
       
   534                 drivers_m->scan(
       
   535                     request_id_m,
       
   536                     core_scan_mode_active,
       
   537                     direct_scanned_ssid_m,
       
   538                     server_m->get_device_settings().scan_rate,
       
   539                     channels,
       
   540                     server_m->get_device_settings().active_scan_min_ch_time,
       
   541                     server_m->get_device_settings().active_scan_max_ch_time,
       
   542                     is_split_scan_m );
       
   543 
       
   544                 break;
       
   545                 }
       
   546             else
       
   547                 {
       
   548                 DEBUG( "core_operation_get_available_iaps_c::next_state() - no reason to direct scan anything" );
       
   549                 remove_non_hidden_iaps();
       
   550 
       
   551                 return goto_state( core_state_scanning_done );
       
   552                 }
       
   553             }
       
   554         case core_state_direct_scan_start:
       
   555             {
       
   556             DEBUG( "core_operation_get_available_iaps_c::next_state() - direct scan request completed, waiting for scan completion" );
       
   557 
       
   558             break;            
       
   559             }
       
   560         case core_state_direct_scan_done:
       
   561             {
       
   562             operation_state_m = core_state_direct_scan_start;
       
   563 
       
   564             DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scan done, %u beacon(s)/probe(s) received",
       
   565                 bss_count_m );
       
   566             DEBUG1( "core_operation_get_available_iaps_c::next_state() - max %u direct scans left",
       
   567                 iap_data_list_m.count() );           
       
   568 
       
   569             /**
       
   570              * Go through the direct scan results and remove the matching IAPs.
       
   571              */
       
   572             process_scan_results(
       
   573                 core_scan_list_tag_direct_scan );
       
   574 
       
   575             /**
       
   576              * If the first entry is still the same the one that was scanned,
       
   577              * it means the IAP was not found.
       
   578              */
       
   579             core_iap_data_s* iap = iap_data_list_m.first();
       
   580             if ( iap && iap->ssid == direct_scanned_ssid_m )
       
   581                 {
       
   582                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - IAP ID %u not found in direct scan",
       
   583                     iap->id );
       
   584 
       
   585                 core_error_e ret = iap_data_list_m.remove( iap );
       
   586                 if( ret != core_error_ok )
       
   587                     {
       
   588                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - error while removing IAP entry (%d)",
       
   589                         ret );
       
   590                     }
       
   591 
       
   592                 non_found_iaps_list_m.append( iap );
       
   593                 }
       
   594 
       
   595             iap = iap_data_list_m.first();
       
   596             if( iap )
       
   597                 {
       
   598                 direct_scanned_ssid_m = iap->ssid;
       
   599                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scanning IAP ID %u",
       
   600                     iap->id );              
       
   601                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   602                     direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   603 
       
   604                 server_m->get_scan_list().set_tag(
       
   605                     core_scan_list_tag_direct_scan );
       
   606 
       
   607                 const core_scan_channels_s& channels(
       
   608                     active_channels_m.channels() );
       
   609                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting scan on channels 0x%02X%02X",
       
   610                     channels.channels2dot4ghz[1],
       
   611                     channels.channels2dot4ghz[0] );
       
   612 
       
   613                 bss_count_m = 0;
       
   614 
       
   615                 server_m->register_event_handler( this );
       
   616                 server_m->register_frame_handler( this );
       
   617 
       
   618                 drivers_m->scan(
       
   619                     request_id_m,
       
   620                     core_scan_mode_active,
       
   621                     direct_scanned_ssid_m,
       
   622                     server_m->get_device_settings().scan_rate,
       
   623                     channels,
       
   624                     server_m->get_device_settings().active_scan_min_ch_time,
       
   625                     server_m->get_device_settings().active_scan_max_ch_time,
       
   626                     is_split_scan_m );
       
   627                 }
       
   628             else
       
   629                 {
       
   630                 DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
       
   631 
       
   632                 return goto_state( core_state_secondary_ssid_check );
       
   633                 }
       
   634 
       
   635             break;
       
   636             }
       
   637         case core_state_secondary_ssid_check:
       
   638             {
       
   639             ASSERT( !iap_data_list_m.count() );
       
   640             ASSERT( !iap_data_list_m.first() );
       
   641 
       
   642             /**
       
   643              * All the IAPs that were not found are contained in non_found_iaps_list_m
       
   644              * list. Those that have secondary SSIDs defined, will be moved back to
       
   645              * iap_data_list_m for scanning.
       
   646              */
       
   647 
       
   648             if ( iap_ssid_list_m )
       
   649                 {
       
   650                 core_iap_data_s* iap = non_found_iaps_list_m.first();
       
   651                 while( iap )
       
   652                     {
       
   653                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - checking IAP ID %u for secondary SSIDs",
       
   654                         iap->id );
       
   655 
       
   656                     if ( is_id_in_secondary_ssid_list( iap->id ) )
       
   657                         {
       
   658                         DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP has secondary SSID(s) defined" );
       
   659 
       
   660                         /** Using a temporary pointer to guarantee list iterator working. */
       
   661                         core_iap_data_s* temp = iap;
       
   662                         iap = non_found_iaps_list_m.next();
       
   663 
       
   664                         non_found_iaps_list_m.remove( temp );
       
   665                         iap_data_list_m.append( temp );
       
   666                         }
       
   667                     else
       
   668                         {
       
   669                         iap = non_found_iaps_list_m.next();
       
   670                         }
       
   671                     }
       
   672                 }
       
   673 
       
   674             if ( !iap_data_list_m.count() )
       
   675                 {
       
   676                 DEBUG( "core_operation_get_available_iaps_c::next_state() - no IAPs with secondary SSID(s) defined" );
       
   677 
       
   678                 return goto_state( core_state_scanning_done );
       
   679                 }
       
   680 
       
   681             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) with secondary SSID(s) defined",
       
   682                 iap_data_list_m.count() );
       
   683 
       
   684             if ( iap_ssid_list_m )
       
   685                 {
       
   686                 (void)iap_ssid_list_m->first();
       
   687                 }
       
   688             (void)iap_data_list_m.first();
       
   689 
       
   690             return goto_state( core_state_secondary_ssid_next );
       
   691             }
       
   692         case core_state_secondary_ssid_next:
       
   693             {
       
   694             operation_state_m = core_state_secondary_ssid_start;
       
   695             
       
   696             core_iap_data_s* iap = iap_data_list_m.current();
       
   697             if ( !iap )
       
   698                 {
       
   699                 DEBUG( "core_operation_get_available_iaps_c::next_state() - all IAPs with secondary SSID(s) handled" );
       
   700 
       
   701                 return goto_state( core_state_scanning_done );
       
   702                 }
       
   703 
       
   704             DEBUG1( "core_operation_get_available_iaps_c::next_state() - current IAP ID %u",
       
   705                 iap->id );
       
   706             core_ssid_entry_s* entry = iap_ssid_list_m->current();
       
   707             while ( entry )
       
   708                 {
       
   709                 if ( iap->id == entry->id )
       
   710                     {
       
   711                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - ID: %u",
       
   712                         entry->id );
       
   713                     DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   714                         entry->ssid.length, entry->ssid.ssid );
       
   715                     DEBUG1S( "core_operation_get_available_iaps_c::next_state() - Used SSID: ",
       
   716                         entry->used_ssid.length, entry->used_ssid.ssid );                    
       
   717  
       
   718                     if ( is_ssid_in_scanlist(
       
   719                             entry->ssid,
       
   720                             client_scan_data_m ) )
       
   721                         {                    
       
   722                         direct_scanned_ssid_m = entry->used_ssid;
       
   723 
       
   724                         DEBUG1S( "core_operation_get_available_iaps_c::next_state() - matching SSID found, doing a direct scan for SSID ",
       
   725                             direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   726 
       
   727                         server_m->get_scan_list().set_tag(
       
   728                             core_scan_list_tag_direct_scan );
       
   729 
       
   730                         const core_scan_channels_s& channels(
       
   731                             active_channels_m.channels() );
       
   732                         DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting scan on channels 0x%02X%02X",
       
   733                             channels.channels2dot4ghz[1],
       
   734                             channels.channels2dot4ghz[0] );
       
   735 
       
   736                         bss_count_m = 0;
       
   737 
       
   738                         server_m->register_event_handler( this );
       
   739                         server_m->register_frame_handler( this );
       
   740 
       
   741                         drivers_m->scan(
       
   742                             request_id_m,
       
   743                             core_scan_mode_active,
       
   744                             direct_scanned_ssid_m,
       
   745                             server_m->get_device_settings().scan_rate,
       
   746                             channels,
       
   747                             server_m->get_device_settings().active_scan_min_ch_time,
       
   748                             server_m->get_device_settings().active_scan_max_ch_time,
       
   749                             is_split_scan_m );                    
       
   750 
       
   751                         return core_error_request_pending;
       
   752                         }
       
   753                     else
       
   754                         {
       
   755                         DEBUG( "core_operation_get_available_iaps_c::next_state() - matching SSID not found, moving to next entry" );
       
   756 
       
   757                         entry = iap_ssid_list_m->next();
       
   758                         }
       
   759                     }
       
   760                 else
       
   761                     {
       
   762                     entry = iap_ssid_list_m->next();
       
   763                     }
       
   764                 }
       
   765 
       
   766             DEBUG1( "core_operation_get_available_iaps_c::next_state() - no more entries for IAP ID %u, moving to next IAP",
       
   767                 iap->id );
       
   768 
       
   769             remove_secondary_ssid_entries_by_id( iap->id );            
       
   770             iap_data_list_m.remove( iap );
       
   771             non_found_iaps_list_m.append( iap );
       
   772             (void)iap_ssid_list_m->first();
       
   773             (void)iap_data_list_m.first();
       
   774 
       
   775             return asynch_goto( core_state_secondary_ssid_next );
       
   776             }
       
   777         case core_state_secondary_ssid_start:
       
   778             {
       
   779             DEBUG( "core_operation_get_available_iaps_c::next_state() - direct scan request completed, waiting for scan completion" );
       
   780 
       
   781             break;
       
   782             }
       
   783         case core_state_secondary_ssid_done:
       
   784             {                
       
   785             core_iap_data_s* iap = iap_data_list_m.current();
       
   786             ASSERT( iap );
       
   787 
       
   788             core_ssid_entry_s* entry = iap_ssid_list_m->current();
       
   789             ASSERT( entry );
       
   790 
       
   791             core_scan_list_iterator_by_tag_and_ssid_c iter(
       
   792                 server_m->get_scan_list(),
       
   793                 core_scan_list_tag_direct_scan,
       
   794                 direct_scanned_ssid_m );
       
   795 
       
   796             for ( core_ap_data_c* ap_data = iter.first(); ap_data; ap_data = iter.next() )
       
   797                 {
       
   798                 core_iap_data_c iap_data( *iap );
       
   799                 if ( core_tools_parser_c::is_ap_compatible_with_iap(
       
   800                     server_m->get_wpx_adaptation_instance(),
       
   801                     *ap_data,
       
   802                     iap_data,
       
   803                     server_m->get_core_settings(),
       
   804                     false_t,
       
   805                     false_t ) == core_connect_ok )
       
   806                     {
       
   807                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - secondary SSID match for IAP ID %u",
       
   808                         iap->id );
       
   809 
       
   810                     u32_t* iap_id = new u32_t;
       
   811                     if( iap_id )
       
   812                         {
       
   813                         *iap_id = iap->id;
       
   814                         iap_id_list_m.append( iap_id );
       
   815                         iap_id = NULL;
       
   816                         }
       
   817 
       
   818                     remove_secondary_ssid_entries_by_id( iap->id );
       
   819                     iap_data_list_m.remove( iap );
       
   820                     (void)iap_ssid_list_m->first();
       
   821                     (void)iap_data_list_m.first();
       
   822                     
       
   823                     delete iap;
       
   824                     iap = NULL;
       
   825 
       
   826                     return goto_state( core_state_secondary_ssid_next );
       
   827                     }
       
   828                 }
       
   829 
       
   830             DEBUG1S( "core_operation_get_available_iaps_c::next_state() - no matching SSID ",
       
   831                 direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   832 
       
   833             (void)iap_ssid_list_m->next();
       
   834 
       
   835             return goto_state( core_state_secondary_ssid_next );
       
   836             }
       
   837         case core_state_scanning_done:
       
   838             {
       
   839             server_m->unregister_frame_handler( this );
       
   840 
       
   841             server_m->get_scan_list().print_contents(); // Additional print            
       
   842 
       
   843             DEBUG( "core_operation_get_available_iaps_c::next_state() - all scanning done" );
       
   844             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list contains %u AP(s)",
       
   845                 client_scan_data_m.Count() );
       
   846             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list size is %u bytes",
       
   847                 client_scan_data_m.Size() );
       
   848             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) found",
       
   849                 iap_id_list_m.count() );
       
   850             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) not found",
       
   851                 non_found_iaps_list_m.count() );
       
   852 
       
   853             /**
       
   854              * Detect channels that have APs with long beacon intervals.
       
   855              */
       
   856             const u32_t long_beacon_interval(
       
   857                 server_m->get_device_settings().passive_scan_max_ch_time );
       
   858 
       
   859             core_long_beacon_interval_channels_s& long_beacon_interval_channels(
       
   860                 server_m->get_core_settings().long_beacon_interval_channels() );
       
   861 
       
   862             core_scan_list_iterator_by_tag_c iter_long_beacon(
       
   863                 server_m->get_scan_list(),
       
   864                 core_scan_list_tag_scan );
       
   865 
       
   866             for ( core_ap_data_c* ap_data = iter_long_beacon.first(); ap_data; ap_data = iter_long_beacon.next() )
       
   867                 {
       
   868                 if ( ap_data->beacon_interval() > long_beacon_interval )
       
   869                     {
       
   870                     const u8_t channel( ap_data->channel() );                    
       
   871                     const core_mac_address_s bssid = ap_data->bssid();
       
   872 
       
   873                     DEBUG8( "core_operation_get_available_iaps_c::next_state() - BSSID %02X:%02X:%02X:%02X:%02X:%02X on channel %u has a long beacon interval (%u)",
       
   874                         bssid.addr[0], bssid.addr[1], bssid.addr[2],
       
   875                         bssid.addr[3], bssid.addr[4], bssid.addr[5],
       
   876                         channel,
       
   877                         ap_data->beacon_interval() );
       
   878                     if ( channel &&
       
   879                          channel <= SCAN_BAND_2DOT4GHZ_MAX_CHANNEL_EURO )
       
   880                         {
       
   881                         long_beacon_interval_channels.channel_scan_count[channel - 1] =
       
   882                             server_m->get_device_settings().long_beacon_find_count;                
       
   883                         }
       
   884                     }
       
   885                 }
       
   886 
       
   887             return core_error_ok;
       
   888             }
       
   889         default:
       
   890             {
       
   891             }
       
   892         }
       
   893 
       
   894     return core_error_request_pending;
       
   895     }
       
   896 
       
   897 // ---------------------------------------------------------------------------
       
   898 // ---------------------------------------------------------------------------
       
   899 //
       
   900 void core_operation_get_available_iaps_c::user_cancel(
       
   901     bool_t do_graceful_cancel )
       
   902     {
       
   903     DEBUG( "core_operation_get_available_iaps_c::user_cancel()" );
       
   904 
       
   905 	/**
       
   906 	 * If region is FCC and region information is not known, then ignore 
       
   907 	 * and remove the APs from channels 12 and 13 
       
   908 	 */
       
   909     if ( !server_m->get_core_settings().mcc_known() && 
       
   910           server_m->get_core_settings().regional_domain() == core_wlan_region_fcc )
       
   911     	{
       
   912     	DEBUG( "core_operation_get_available_iaps_c::next_state() - remove APs that were found on channels 12 and 13" );
       
   913     	remove_disallowed_aps();            	
       
   914     	}
       
   915     
       
   916     if ( !do_graceful_cancel )
       
   917         {
       
   918         /**
       
   919          * If we are in a middle of a scan, we have to schedule our own
       
   920          * event.
       
   921          */
       
   922         if ( ( operation_state_m == core_state_long_broadcast_scan_start ||
       
   923                operation_state_m == core_state_broadcast_scan_start ||
       
   924                operation_state_m == core_state_broadcast_scan_start_unknown_region ||
       
   925                operation_state_m == core_state_direct_scan_start ||
       
   926                operation_state_m == core_state_secondary_ssid_start ) &&         
       
   927             server_m->event_handler() == this &&
       
   928             server_m->frame_handler() == this )
       
   929             {
       
   930             asynch_default_user_cancel();
       
   931 
       
   932             return;
       
   933             }
       
   934 
       
   935         /**
       
   936          * Everything else is handled by the default implementation.
       
   937          */
       
   938         core_operation_base_c::user_cancel( do_graceful_cancel );
       
   939         }
       
   940     }
       
   941 
       
   942 // ---------------------------------------------------------------------------
       
   943 // ---------------------------------------------------------------------------
       
   944 //
       
   945 void core_operation_get_available_iaps_c::remove_non_hidden_iaps()
       
   946     {
       
   947     DEBUG("core_operation_get_available_iaps_c::remove_non_hidden_iaps()");
       
   948 
       
   949     core_iap_data_s* iap = iap_data_list_m.first();
       
   950     while( iap )
       
   951         {
       
   952         if( !iap->is_hidden )
       
   953             {
       
   954             DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - removing IAP ID %u",
       
   955                 iap->id );
       
   956             
       
   957             core_iap_data_s* temp = iap;
       
   958             iap = iap_data_list_m.next();
       
   959             core_error_e ret = iap_data_list_m.remove( temp );
       
   960             if( ret != core_error_ok )
       
   961                 {
       
   962                 DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - error while removing IAP entry (%d)",
       
   963                     ret );
       
   964                 }
       
   965             non_found_iaps_list_m.append( temp );
       
   966             }
       
   967         else
       
   968             {
       
   969             DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - leaving IAP ID %u",
       
   970                 iap->id );
       
   971 
       
   972             iap = iap_data_list_m.next();
       
   973             }
       
   974         }
       
   975     }
       
   976 
       
   977 // ---------------------------------------------------------------------------
       
   978 // ---------------------------------------------------------------------------
       
   979 //
       
   980 void core_operation_get_available_iaps_c::process_scan_results(
       
   981     u8_t tag )
       
   982     {
       
   983     DEBUG( "core_operation_get_available_iaps_c::process_scan_results()" );
       
   984 
       
   985     core_scan_list_iterator_by_tag_c iter(
       
   986         server_m->get_scan_list(),
       
   987         tag );
       
   988 
       
   989     for ( core_ap_data_c* ap_data = iter.first(); ap_data; ap_data = iter.next() )
       
   990         {
       
   991         remove_matching_iaps( *ap_data );
       
   992         }
       
   993     }
       
   994 
       
   995 // ---------------------------------------------------------------------------
       
   996 // ---------------------------------------------------------------------------
       
   997 //
       
   998 void core_operation_get_available_iaps_c::remove_matching_iaps(
       
   999     core_ap_data_c& ap_data )
       
  1000     {
       
  1001     DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps()" );
       
  1002         
       
  1003     if ( ap_data.rcpi() < server_m->get_device_settings().iap_availability_rcpi_threshold )
       
  1004         {
       
  1005         DEBUG2( "core_operation_get_available_iaps_c::remove_matching_iaps() - AP not considered, signal too weak (%u vs %u)",
       
  1006             ap_data.rcpi(), server_m->get_device_settings().iap_availability_rcpi_threshold );
       
  1007 
       
  1008         return;
       
  1009         }
       
  1010     
       
  1011     u8_t treshold_val = 
       
  1012         static_cast<u8_t>(server_m->get_core_settings().rcp_improve_boundary());
       
  1013         
       
  1014     /**
       
  1015      * Loop through the IAP list.
       
  1016      */
       
  1017     core_iap_data_s* iap = iap_data_list_m.first();
       
  1018     while( iap )
       
  1019         {
       
  1020         core_iap_data_c iap_data( *iap );
       
  1021         if ( iap->ssid == ap_data.ssid() &&
       
  1022              core_tools_parser_c::is_ap_compatible_with_iap(
       
  1023                 server_m->get_wpx_adaptation_instance(),
       
  1024                 ap_data,
       
  1025                 iap_data,
       
  1026                 server_m->get_core_settings(),
       
  1027                 false_t,
       
  1028                 false_t ) == core_connect_ok )
       
  1029             {
       
  1030             DEBUG1("core_operation_get_available_iaps_c::remove_matching_iaps() - match found for IAP ID %u",
       
  1031                 iap->id );            
       
  1032 
       
  1033             u32_t* iap_id = new u32_t;
       
  1034             if( iap_id )
       
  1035                 {
       
  1036                 if ( server_m->get_core_settings().is_iap_id_in_weak_list( iap->id) ) 
       
  1037                     {
       
  1038                     DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps() - IAP ID is in weak list" );
       
  1039                     
       
  1040                     if ( ap_data.rcpi() > treshold_val )
       
  1041                         {
       
  1042                         DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps() - RCPI improved enough, remove IAP ID from weak list" );
       
  1043                         *iap_id = iap->id;
       
  1044                         iap_id_list_m.append( iap_id );
       
  1045             		    iap_id = NULL;
       
  1046                         
       
  1047                         server_m->get_core_settings().remove_iap_id_from_weak_list( iap->id );
       
  1048                         }
       
  1049 
       
  1050                     }
       
  1051                 else
       
  1052                     {
       
  1053                     *iap_id = iap->id;
       
  1054                     iap_id_list_m.append( iap_id );
       
  1055                     iap_id = NULL;
       
  1056                     }
       
  1057                 }
       
  1058 
       
  1059             /** Using a temporary pointer to guarantee list iterator working. */
       
  1060             core_iap_data_s* temp = iap;
       
  1061             
       
  1062             iap = iap_data_list_m.next();
       
  1063             core_error_e ret = iap_data_list_m.remove( temp );
       
  1064             if( ret != core_error_ok )
       
  1065                 {
       
  1066                 if( iap )
       
  1067                     {
       
  1068                     DEBUG1("core_operation_get_available_iaps_c::remove_matching_iaps() - error while removing IAP entry (%d)",
       
  1069                         iap->id );                   
       
  1070                     }
       
  1071                 }
       
  1072 
       
  1073             delete temp;
       
  1074             temp = NULL;
       
  1075             delete iap_id;
       
  1076             iap_id = NULL;
       
  1077             }
       
  1078         else
       
  1079             {
       
  1080             iap = iap_data_list_m.next();
       
  1081             }
       
  1082         }
       
  1083     }
       
  1084 
       
  1085 // ---------------------------------------------------------------------------
       
  1086 // ---------------------------------------------------------------------------
       
  1087 //
       
  1088 u8_t core_operation_get_available_iaps_c::hidden_iap_count(
       
  1089     core_type_list_c<core_iap_data_s>& iap_data_list )
       
  1090     {
       
  1091     DEBUG( "core_operation_get_available_iaps_c::hidden_iap_count()" );
       
  1092 
       
  1093     u8_t count( 0 );
       
  1094     core_iap_data_s* iap = iap_data_list.first();
       
  1095 
       
  1096     while( iap )
       
  1097         {
       
  1098         if( iap->is_hidden )
       
  1099             {
       
  1100             ++count;
       
  1101             }
       
  1102 
       
  1103         iap = iap_data_list.next();
       
  1104         }
       
  1105 
       
  1106     return count;
       
  1107     }
       
  1108 
       
  1109 // ---------------------------------------------------------------------------
       
  1110 // ---------------------------------------------------------------------------
       
  1111 //
       
  1112 void core_operation_get_available_iaps_c::remove_disallowed_aps()
       
  1113     {
       
  1114     core_type_list_c<core_mac_address_s> remove_ap_list;
       
  1115                 
       
  1116     core_scan_list_iterator_by_tag_c iter_removed_aps(
       
  1117         server_m->get_scan_list(),
       
  1118         core_scan_list_tag_scan );
       
  1119 
       
  1120     core_ap_data_c* ap_data = iter_removed_aps.first();
       
  1121     while ( ap_data )
       
  1122         {
       
  1123         if ( !server_m->get_core_settings().is_valid_channel(
       
  1124                 SCAN_BAND_2DOT4GHZ,
       
  1125                 ap_data->channel() ) )
       
  1126             {
       
  1127             core_mac_address_s* ignored_ap = new core_mac_address_s;
       
  1128             if ( ignored_ap )
       
  1129                 {
       
  1130                 *ignored_ap = ap_data->bssid();
       
  1131                 remove_ap_list.append( ignored_ap );
       
  1132                 }
       
  1133             }
       
  1134 
       
  1135         ap_data = iter_removed_aps.next(); 
       
  1136         }
       
  1137 
       
  1138     core_mac_address_s* ignored_bssid = remove_ap_list.first(); 
       
  1139     while (ignored_bssid )
       
  1140         {
       
  1141         server_m->get_scan_list().remove_entries_by_bssid( *ignored_bssid );
       
  1142         ignored_bssid = remove_ap_list.next();
       
  1143         }
       
  1144 
       
  1145     remove_ap_list.clear();    
       
  1146     }
       
  1147 
       
  1148 // ---------------------------------------------------------------------------
       
  1149 // ---------------------------------------------------------------------------
       
  1150 //
       
  1151 bool_t core_operation_get_available_iaps_c::is_id_in_secondary_ssid_list(
       
  1152     u32_t id )
       
  1153     {
       
  1154     for( core_ssid_entry_s* iter = iap_ssid_list_m->first(); iter; iter = iap_ssid_list_m->next() )
       
  1155         {
       
  1156         if ( id == iter->id )
       
  1157             {
       
  1158             return true_t;
       
  1159             }
       
  1160         }
       
  1161 
       
  1162     return false_t;
       
  1163     }
       
  1164 
       
  1165 // ---------------------------------------------------------------------------
       
  1166 // ---------------------------------------------------------------------------
       
  1167 //
       
  1168 void core_operation_get_available_iaps_c::remove_secondary_ssid_entries_by_id(
       
  1169     u32_t id )
       
  1170     {
       
  1171     core_ssid_entry_s* iter = iap_ssid_list_m->first();
       
  1172     while( iter )
       
  1173         {
       
  1174         if ( id == iter->id )
       
  1175             {
       
  1176             /** Using a temporary pointer to guarantee list iterator working. */
       
  1177             core_ssid_entry_s* temp = iter;
       
  1178             iter = iap_ssid_list_m->next();
       
  1179 
       
  1180             core_error_e ret = iap_ssid_list_m->remove( temp );
       
  1181             if( ret != core_error_ok )
       
  1182                 {
       
  1183                 DEBUG1("core_operation_get_available_iaps_c::remove_secondary_ssid_entries_by_id() - error while removing an entry (%u)",
       
  1184                     ret );
       
  1185                 }
       
  1186             
       
  1187             delete temp;
       
  1188             temp = NULL;
       
  1189             }
       
  1190         else
       
  1191             {
       
  1192             iter = iap_ssid_list_m->next();
       
  1193             }
       
  1194         }
       
  1195     }
       
  1196 
       
  1197 // ---------------------------------------------------------------------------
       
  1198 // ---------------------------------------------------------------------------
       
  1199 //
       
  1200 bool_t core_operation_get_available_iaps_c::is_ssid_in_scanlist(
       
  1201     const core_ssid_s& ssid,
       
  1202     const ScanList& scan_data )
       
  1203     {
       
  1204     u8_t ie_len( 0 );
       
  1205     const u8_t* ie_data = NULL;
       
  1206     ScanInfo info( scan_data );
       
  1207 
       
  1208     for ( info.First(); !info.IsDone(); info.Next() )
       
  1209         {
       
  1210         if( !info.InformationElement( core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_ssid, ie_len, &ie_data ) )
       
  1211             {
       
  1212             if( core_tools_c::compare(
       
  1213                 ssid.ssid, ssid.length,
       
  1214                 ie_data, ie_len ) == 0 )
       
  1215                 {
       
  1216                 return true_t;
       
  1217                 }
       
  1218             }
       
  1219         }
       
  1220 
       
  1221     return false_t;
       
  1222     }
       
  1223 
       
  1224 // ---------------------------------------------------------------------------
       
  1225 // ---------------------------------------------------------------------------
       
  1226 //    
       
  1227 bool_t core_operation_get_available_iaps_c::receive_frame(
       
  1228     const core_frame_dot11_c* frame,
       
  1229     u8_t rcpi )
       
  1230     {
       
  1231     DEBUG( "core_operation_get_available_iaps_c::receive_frame()" );
       
  1232 
       
  1233     if ( frame->type() != core_frame_dot11_c::core_dot11_type_beacon &&
       
  1234          frame->type() != core_frame_dot11_c::core_dot11_type_probe_resp )
       
  1235         {
       
  1236         DEBUG( "core_operation_get_available_iaps_c::receive_frame() - not a beacon or a probe" );        
       
  1237         return false_t;
       
  1238         }
       
  1239 
       
  1240     core_ap_data_c* ap_data = core_ap_data_c::instance(
       
  1241         server_m->get_wpx_adaptation_instance(),
       
  1242         frame,
       
  1243         rcpi,
       
  1244         false_t );
       
  1245     if ( ap_data )
       
  1246         {        
       
  1247         const core_ssid_s ssid = ap_data->ssid();
       
  1248         DEBUG1S( "core_operation_get_available_iaps_c::receive_frame() - SSID: ",
       
  1249             ssid.length, &ssid.ssid[0] );
       
  1250 
       
  1251         const core_mac_address_s bssid = ap_data->bssid();
       
  1252         DEBUG6( "core_operation_get_available_iaps_c::receive_frame() - BSSID: %02X:%02X:%02X:%02X:%02X:%02X",
       
  1253             bssid.addr[0], bssid.addr[1], bssid.addr[2], 
       
  1254             bssid.addr[3], bssid.addr[4], bssid.addr[5] );        
       
  1255 
       
  1256         server_m->get_scan_list().update_entry( *ap_data );
       
  1257 
       
  1258         active_channels_m.add(
       
  1259             ap_data->band(),
       
  1260             ap_data->channel() );
       
  1261 
       
  1262         bss_count_m++;
       
  1263 
       
  1264         delete ap_data;
       
  1265         ap_data = NULL;
       
  1266         }
       
  1267 
       
  1268     return true_t;
       
  1269     }
       
  1270 
       
  1271 // ---------------------------------------------------------------------------
       
  1272 // ---------------------------------------------------------------------------
       
  1273 //
       
  1274 bool_t core_operation_get_available_iaps_c::notify(
       
  1275     core_am_indication_e indication )
       
  1276     {
       
  1277     if ( indication == core_am_indication_wlan_scan_complete )
       
  1278         {
       
  1279         server_m->unregister_event_handler( this );
       
  1280 
       
  1281         if ( operation_state_m == core_state_long_broadcast_scan_start )
       
  1282             {
       
  1283             DEBUG( "core_operation_get_available_iaps_c::notify() - long broadcast scan complete" );
       
  1284 
       
  1285             asynch_goto( core_state_long_broadcast_scan_done, CORE_TIMER_IMMEDIATELY );
       
  1286             }
       
  1287         else if ( operation_state_m == core_state_broadcast_scan_start )
       
  1288             {
       
  1289             DEBUG( "core_operation_get_available_iaps_c::notify() - broadcast scan complete" );
       
  1290 
       
  1291             asynch_goto( core_state_broadcast_scan_done, CORE_TIMER_IMMEDIATELY );
       
  1292             }
       
  1293         else if ( operation_state_m == core_state_broadcast_scan_start_unknown_region )
       
  1294         	{
       
  1295         	DEBUG( "core_operation_get_available_iaps_c::notify() - broadcast scan complete for channels 12 and 13" );
       
  1296         	
       
  1297         	asynch_goto( core_state_broadcast_scan_complete_unknown_region, CORE_TIMER_IMMEDIATELY );
       
  1298         	}
       
  1299         else if ( operation_state_m == core_state_direct_scan_start )
       
  1300             {
       
  1301             DEBUG( "core_operation_get_available_iaps_c::notify() - direct scan complete" );
       
  1302 
       
  1303             asynch_goto( core_state_direct_scan_done, CORE_TIMER_IMMEDIATELY );
       
  1304             }
       
  1305         else if ( operation_state_m == core_state_secondary_ssid_start )
       
  1306             {
       
  1307             DEBUG( "core_operation_get_available_iaps_c::notify() - direct scan complete" );
       
  1308 
       
  1309             asynch_goto( core_state_secondary_ssid_done, CORE_TIMER_IMMEDIATELY );
       
  1310             }
       
  1311         else
       
  1312             {
       
  1313             DEBUG( "core_operation_get_available_iaps_c::notify() - scan complete in unknown state" );
       
  1314             ASSERT( false_t );
       
  1315             }
       
  1316 
       
  1317         return true_t;
       
  1318         }
       
  1319 
       
  1320     return false_t;
       
  1321     }