wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_get_available_iaps.cpp
branchRCL_3
changeset 14 13838cf40350
parent 6 e0f767079796
equal deleted inserted replaced
12:af3fb27c7511 14:13838cf40350
    14 * Description:  State machine for IAP availability.
    14 * Description:  State machine for IAP availability.
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 /*
    18 /*
    19 * %version: 41 %
    19 * %version: 44 %
    20 */
    20 */
    21 
    21 
    22 #include "core_operation_get_available_iaps.h"
    22 #include "core_operation_get_available_iaps.h"
    23 #include "core_server.h"
    23 #include "core_server.h"
    24 #include "core_tools.h"
    24 #include "core_tools.h"
    25 #include "core_tools_parser.h"
    25 #include "core_tools_parser.h"
    26 #include "core_frame_dot11.h"
    26 #include "core_frame_dot11.h"
    27 #include "core_frame_dot11_ie.h"
    27 #include "core_frame_dot11_ie.h"
    28 #include "am_debug.h"
    28 #include "am_debug.h"
    29 
    29 
    30 /** Defining this enables IAP related traces. */
    30 /** 
    31 //#define WLAN_CORE_DEEP_DEBUG 1
    31  * The channel time used in the long passive scan.
    32 
    32  */
    33 /** The channel time used in the long passive scan. */
       
    34 const u32_t LONG_PASSIVE_SCAN_CHANNEL_TIME = 210;
    33 const u32_t LONG_PASSIVE_SCAN_CHANNEL_TIME = 210;
    35 
    34 
    36 /**
    35 /**
    37  * If the phone has at least this many IAPs marked as hidden,
    36  * If the phone has at least this many IAPs marked as hidden,
    38  * limiting algorithm will be used for detecting available IAPs.
    37  * limiting algorithm will be used for detecting available IAPs.
    49     core_server_c* server,        
    48     core_server_c* server,        
    50     abs_core_driverif_c* drivers,
    49     abs_core_driverif_c* drivers,
    51     abs_core_server_callback_c* adaptation,
    50     abs_core_server_callback_c* adaptation,
    52     bool_t is_active_scan_allowed,
    51     bool_t is_active_scan_allowed,
    53     core_type_list_c<core_iap_data_s>& iap_data_list,
    52     core_type_list_c<core_iap_data_s>& iap_data_list,
    54     core_type_list_c<u32_t>& iap_id_list,
    53     core_type_list_c<core_iap_availability_data_s>& iap_availability_list,
    55     core_type_list_c<core_ssid_entry_s>* iap_ssid_list,
    54     core_type_list_c<core_ssid_entry_s>* iap_ssid_list,
    56     ScanList& scan_data ) :
    55     ScanList& scan_data ) :
    57     core_operation_base_c( core_operation_get_available_iaps, request_id, server, drivers, adaptation,
    56     core_operation_base_c( core_operation_get_available_iaps, request_id, server, drivers, adaptation,
    58         core_base_flag_drivers_needed ),    
    57         core_base_flag_drivers_needed ),    
    59     is_active_scan_allowed_m( is_active_scan_allowed ),
    58     is_active_scan_allowed_m( is_active_scan_allowed ),
    60     is_limiting_algorithm_used_m( false_t ),
    59     is_limiting_algorithm_used_m( false_t ),
       
    60     iap_data_count_m( iap_data_list.count() ),
    61     iap_data_list_m( iap_data_list ),
    61     iap_data_list_m( iap_data_list ),
    62     iap_id_list_m( iap_id_list ),
    62     iap_availability_list_m( iap_availability_list ),
    63     iap_ssid_list_m( iap_ssid_list ),
    63     iap_ssid_list_m( iap_ssid_list ),
    64     client_scan_data_m( scan_data ),
    64     client_scan_data_m( scan_data ),
    65     active_channels_m( ),
    65     active_channels_m( ),
    66     broadcast_channels_m( ),
    66     broadcast_channels_m( ),
    67     long_broadcast_count_m( 0 ),
    67     long_broadcast_count_m( 0 ),
    68     non_found_iaps_list_m( ),
       
    69     is_split_scan_m( false_t ),
    68     is_split_scan_m( false_t ),
    70     bss_count_m( 0 ),
    69     bss_count_m( 0 ),
    71     direct_scanned_ssid_m( ),
    70     direct_scan_iter_m( direct_scan_list_m ), 
    72     region_from_ap_m( core_wlan_region_fcc )
    71     region_from_ap_m( core_wlan_region_fcc )
    73     {
    72     {
    74     DEBUG( "core_operation_get_available_iaps_c::core_operation_get_available_iaps_c()" );
    73     DEBUG( "core_operation_get_available_iaps_c::core_operation_get_available_iaps_c()" );
    75     }
    74     }
    76 
    75 
    81     {
    80     {
    82     DEBUG( "core_operation_get_available_iaps_c::~core_operation_get_available_iaps_c()" );
    81     DEBUG( "core_operation_get_available_iaps_c::~core_operation_get_available_iaps_c()" );
    83 
    82 
    84     server_m->unregister_event_handler( this );
    83     server_m->unregister_event_handler( this );
    85     server_m->unregister_frame_handler( this );
    84     server_m->unregister_frame_handler( this );
    86     non_found_iaps_list_m.clear();
    85     direct_scan_list_m.clear();
    87     iap_ssid_list_m = NULL;
    86     iap_ssid_list_m = NULL;
    88     }
    87     }
    89 
    88 
    90 // ---------------------------------------------------------------------------
    89 // ---------------------------------------------------------------------------
    91 // ---------------------------------------------------------------------------
    90 // ---------------------------------------------------------------------------
   101             operation_state_m = core_state_long_broadcast_scan_start;
   100             operation_state_m = core_state_long_broadcast_scan_start;
   102 
   101 
   103 #ifdef WLAN_CORE_DEEP_DEBUG
   102 #ifdef WLAN_CORE_DEEP_DEBUG
   104             DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP data list:" );
   103             DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP data list:" );
   105 
   104 
   106             core_iap_data_s* iter_data = iap_data_list_m.first();            
   105             core_type_list_iterator_c<core_iap_data_s> iap_data_iter( iap_data_list_m );
   107             while( iter_data )
   106             for( core_iap_data_s* entry = iap_data_iter.first(); entry; entry = iap_data_iter.next() )
   108                 {
   107                 {
   109                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - ID: %u",
   108                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - ID: %u",
   110                     iter_data->id );
   109                     entry->id );
   111                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
   110                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
   112                     iter_data->ssid.length, iter_data->ssid.ssid );
   111                     entry->ssid.length, entry->ssid.ssid );
   113 
       
   114                 iter_data = iap_data_list_m.next();
       
   115                 }
   112                 }
   116 
   113 
   117             if ( iap_ssid_list_m )
   114             if ( iap_ssid_list_m )
   118                 {
   115                 {
   119                 DEBUG( "core_operation_get_available_iaps_c::next_state()" );
   116                 DEBUG( "core_operation_get_available_iaps_c::next_state()" );
   255                 }
   252                 }
   256 
   253 
   257             const core_scan_channels_s channels(
   254             const core_scan_channels_s channels(
   258                 server_m->get_core_settings().valid_scan_channels( broadcast_channels_m.channels() ) );
   255                 server_m->get_core_settings().valid_scan_channels( broadcast_channels_m.channels() ) );
   259 
   256 
   260 
       
   261             if ( !is_active_scan_allowed_m ||
   257             if ( !is_active_scan_allowed_m ||
   262                  is_limiting_algorithm_used_m )
   258                  is_limiting_algorithm_used_m )
   263                 {
   259                 {
   264                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting passive broadcast scan on channels 0x%02X%02X",
   260                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting passive broadcast scan on channels 0x%02X%02X",
   265                     channels.channels2dot4ghz[1],
   261                     channels.channels2dot4ghz[1],
   320             	{
   316             	{
   321             	/* When WLAN region is known, the allowed scan channels are known and 
   317             	/* When WLAN region is known, the allowed scan channels are known and 
   322             	 * handled already */
   318             	 * handled already */
   323             	return goto_state( core_state_broadcast_scan_done_handle_result );
   319             	return goto_state( core_state_broadcast_scan_done_handle_result );
   324             	}
   320             	}
   325             
   321 
   326             operation_state_m = core_state_broadcast_scan_start_unknown_region;
   322             operation_state_m = core_state_broadcast_scan_start_unknown_region;
   327 
   323 
   328             broadcast_channels_m.set(
   324             broadcast_channels_m.set(
   329                     server_m->get_core_settings().all_valid_scan_channels() );
   325                     server_m->get_core_settings().all_valid_scan_channels() );
   330             
   326             
   470                         ap_data->rcpi() );
   466                         ap_data->rcpi() );
   471                     }
   467                     }
   472                 }
   468                 }
   473 
   469 
   474             /**
   470             /**
   475              * Go through the broadcast scan results and remove matching IAPs.
   471              * Go through the broadcast scan results.
   476              */
   472              */
   477             process_scan_results(
   473             process_scan_results(
   478                 core_scan_list_tag_scan );
   474                 core_scan_list_tag_scan );
   479 
   475 
   480             /**
   476             /**
   485                    !is_limiting_algorithm_used_m ) ||
   481                    !is_limiting_algorithm_used_m ) ||
   486                  ( is_active_scan_allowed_m &&
   482                  ( is_active_scan_allowed_m &&
   487                    is_limiting_algorithm_used_m &&
   483                    is_limiting_algorithm_used_m &&
   488                    bss_count_m ) )
   484                    bss_count_m ) )
   489                 {
   485                 {
   490                 remove_non_hidden_iaps();
   486                 /**
       
   487                  * Gather a list of SSID to direct scan. Only IAPs marked
       
   488                  * as hidden will be scanned. 
       
   489                  */
       
   490                 core_type_list_iterator_c<core_iap_data_s> iap_data_iter( iap_data_list_m );
       
   491                 for( core_iap_data_s* entry = iap_data_iter.first(); entry; entry = iap_data_iter.next() )
       
   492                     {
       
   493                     if( entry->is_hidden &&
       
   494                         !is_ssid_in_list(
       
   495                             entry->ssid,
       
   496                             direct_scan_list_m ) )
       
   497                         {
       
   498                         core_ssid_s* ssid = new core_ssid_s;
       
   499                         if( ssid )
       
   500                             {
       
   501                             *ssid = entry->ssid;
       
   502                             core_error_e ret = direct_scan_list_m.append( ssid );
       
   503                             if( ret != core_error_ok )
       
   504                                 {
       
   505                                 delete ssid;
       
   506                                 }
       
   507                             ssid = NULL;
       
   508                             }
       
   509                         }
       
   510                     }
   491 
   511 
   492                 /**
   512                 /**
   493                  * If limiting algorithm is used, only the current active_channels_m
   513                  * If limiting algorithm is used, only the current active_channels_m
   494                  * will be used.
   514                  * will be used.
   495                  */               
   515                  */               
   496                 if ( is_limiting_algorithm_used_m )
   516                 if( is_limiting_algorithm_used_m )
   497                     {
   517                     {
   498                     DEBUG( "core_operation_get_available_iaps_c::next_state() - limiting channels based on WLAN activity" );
   518                     DEBUG( "core_operation_get_available_iaps_c::next_state() - limiting channels based on WLAN activity" );
   499                     }
   519                     }
   500                 else
   520                 else
   501                     {
   521                     {
   502                     active_channels_m.set(
   522                     active_channels_m.set(
   503                         server_m->get_core_settings().all_valid_scan_channels() );
   523                         server_m->get_core_settings().all_valid_scan_channels() );
   504                     }
   524                     }
   505 
   525 
   506                 /**
   526                 core_ssid_s* ssid = direct_scan_iter_m.first();
   507                  * iap_data_list_m now contains only hidden ssid IAPs,
   527                 if( !ssid )
   508                  * that will be direct scanned next.
       
   509                  */
       
   510                 core_iap_data_s* iap = iap_data_list_m.first();
       
   511                 if( !iap )
       
   512                     {
   528                     {
   513                     DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
   529                     DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
   514 
   530 
   515                     /** No hidden IAP entries in the request, move on.. */
       
   516                     return goto_state( core_state_secondary_ssid_check );
   531                     return goto_state( core_state_secondary_ssid_check );
   517                     }
   532                     }
   518 
   533 
   519                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - going to direct scan %u IAP(s)",
   534                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - going to direct scan %u SSID(s)",
   520                     iap_data_list_m.count() );
   535                     direct_scan_list_m.count() );
   521 
   536                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - direct scanning SSID: ",
   522                 direct_scanned_ssid_m = iap->ssid;
   537                     ssid->length, &ssid->ssid[0] );
   523                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scanning IAP ID %u",
       
   524                     iap->id );
       
   525                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   526                     direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   527 
   538 
   528                 server_m->get_scan_list().set_tag(
   539                 server_m->get_scan_list().set_tag(
   529                     core_scan_list_tag_direct_scan );
   540                     core_scan_list_tag_direct_scan );
   530 
   541 
   531                 const core_scan_channels_s& channels(
   542                 const core_scan_channels_s& channels(
   540                 server_m->register_frame_handler( this );
   551                 server_m->register_frame_handler( this );
   541 
   552 
   542                 drivers_m->scan(
   553                 drivers_m->scan(
   543                     request_id_m,
   554                     request_id_m,
   544                     core_scan_mode_active,
   555                     core_scan_mode_active,
   545                     direct_scanned_ssid_m,
   556                     *ssid,
   546                     server_m->get_device_settings().scan_rate,
   557                     server_m->get_device_settings().scan_rate,
   547                     channels,
   558                     channels,
   548                     server_m->get_device_settings().active_scan_min_ch_time,
   559                     server_m->get_device_settings().active_scan_min_ch_time,
   549                     server_m->get_device_settings().active_scan_max_ch_time,
   560                     server_m->get_device_settings().active_scan_max_ch_time,
   550                     is_split_scan_m );
   561                     is_split_scan_m );
   552                 break;
   563                 break;
   553                 }
   564                 }
   554             else
   565             else
   555                 {
   566                 {
   556                 DEBUG( "core_operation_get_available_iaps_c::next_state() - no reason to direct scan anything" );
   567                 DEBUG( "core_operation_get_available_iaps_c::next_state() - no reason to direct scan anything" );
   557                 remove_non_hidden_iaps();
       
   558 
   568 
   559                 return goto_state( core_state_scanning_done );
   569                 return goto_state( core_state_scanning_done );
   560                 }
   570                 }
   561             }
   571             }
   562         case core_state_direct_scan_start:
   572         case core_state_direct_scan_start:
   569             {
   579             {
   570             operation_state_m = core_state_direct_scan_start;
   580             operation_state_m = core_state_direct_scan_start;
   571 
   581 
   572             DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scan done, %u beacon(s)/probe(s) received",
   582             DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scan done, %u beacon(s)/probe(s) received",
   573                 bss_count_m );
   583                 bss_count_m );
   574             DEBUG1( "core_operation_get_available_iaps_c::next_state() - max %u direct scans left",
       
   575                 iap_data_list_m.count() );           
       
   576 
   584 
   577             /**
   585             /**
   578              * Go through the direct scan results and remove the matching IAPs.
   586              * Go through the direct scan results and remove the matching IAPs.
   579              */
   587              */
   580             process_scan_results(
   588             process_scan_results(
   581                 core_scan_list_tag_direct_scan );
   589                 core_scan_list_tag_direct_scan );
   582 
   590 
       
   591             core_ssid_s* ssid = direct_scan_iter_m.next();
       
   592             if( !ssid )
       
   593                 {
       
   594                 DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
       
   595 
       
   596                 return goto_state( core_state_secondary_ssid_check );
       
   597                 }
       
   598 
       
   599             DEBUG1S( "core_operation_get_available_iaps_c::next_state() - direct scanning SSID: ",
       
   600                 ssid->length, &ssid->ssid[0] );
       
   601 
       
   602             server_m->get_scan_list().set_tag(
       
   603                 core_scan_list_tag_direct_scan );
       
   604 
       
   605             const core_scan_channels_s& channels(
       
   606                 active_channels_m.channels() );
       
   607             DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting scan on channels 0x%02X%02X",
       
   608                 channels.channels2dot4ghz[1],
       
   609                 channels.channels2dot4ghz[0] );
       
   610 
       
   611             bss_count_m = 0;
       
   612 
       
   613             server_m->register_event_handler( this );
       
   614             server_m->register_frame_handler( this );
       
   615 
       
   616             drivers_m->scan(
       
   617                 request_id_m,
       
   618                 core_scan_mode_active,
       
   619                 *ssid,
       
   620                 server_m->get_device_settings().scan_rate,
       
   621                 channels,
       
   622                 server_m->get_device_settings().active_scan_min_ch_time,
       
   623                 server_m->get_device_settings().active_scan_max_ch_time,
       
   624                 is_split_scan_m );
       
   625 
       
   626             break;
       
   627             }
       
   628         case core_state_secondary_ssid_check:
       
   629             {
   583             /**
   630             /**
   584              * If the first entry is still the same the one that was scanned,
   631              * Remove all IAPs that have either been found or don't have
   585              * it means the IAP was not found.
   632              * secondary SSID defined.
   586              */
   633              */
   587             core_iap_data_s* iap = iap_data_list_m.first();
   634             if( iap_ssid_list_m )
   588             if ( iap && iap->ssid == direct_scanned_ssid_m )
   635                 {
   589                 {
   636                 core_type_list_iterator_c<core_iap_data_s> iap_data_iter( iap_data_list_m );
   590                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - IAP ID %u not found in direct scan",
   637                 for( core_iap_data_s* entry = iap_data_iter.first(); entry; entry = iap_data_iter.next() )
   591                     iap->id );
       
   592 
       
   593                 core_error_e ret = iap_data_list_m.remove( iap );
       
   594                 if( ret != core_error_ok )
       
   595                     {
       
   596                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - error while removing IAP entry (%d)",
       
   597                         ret );
       
   598                     }
       
   599 
       
   600                 non_found_iaps_list_m.append( iap );
       
   601                 }
       
   602 
       
   603             iap = iap_data_list_m.first();
       
   604             if( iap )
       
   605                 {
       
   606                 direct_scanned_ssid_m = iap->ssid;
       
   607                 DEBUG1( "core_operation_get_available_iaps_c::next_state() - direct scanning IAP ID %u",
       
   608                     iap->id );              
       
   609                 DEBUG1S( "core_operation_get_available_iaps_c::next_state() - SSID: ",
       
   610                     direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
       
   611 
       
   612                 server_m->get_scan_list().set_tag(
       
   613                     core_scan_list_tag_direct_scan );
       
   614 
       
   615                 const core_scan_channels_s& channels(
       
   616                     active_channels_m.channels() );
       
   617                 DEBUG2( "core_operation_get_available_iaps_c::next_state() - requesting scan on channels 0x%02X%02X",
       
   618                     channels.channels2dot4ghz[1],
       
   619                     channels.channels2dot4ghz[0] );
       
   620 
       
   621                 bss_count_m = 0;
       
   622 
       
   623                 server_m->register_event_handler( this );
       
   624                 server_m->register_frame_handler( this );
       
   625 
       
   626                 drivers_m->scan(
       
   627                     request_id_m,
       
   628                     core_scan_mode_active,
       
   629                     direct_scanned_ssid_m,
       
   630                     server_m->get_device_settings().scan_rate,
       
   631                     channels,
       
   632                     server_m->get_device_settings().active_scan_min_ch_time,
       
   633                     server_m->get_device_settings().active_scan_max_ch_time,
       
   634                     is_split_scan_m );
       
   635                 }
       
   636             else
       
   637                 {
       
   638                 DEBUG( "core_operation_get_available_iaps_c::next_state() - nothing to direct scan" );
       
   639 
       
   640                 return goto_state( core_state_secondary_ssid_check );
       
   641                 }
       
   642 
       
   643             break;
       
   644             }
       
   645         case core_state_secondary_ssid_check:
       
   646             {
       
   647             ASSERT( !iap_data_list_m.count() );
       
   648             ASSERT( !iap_data_list_m.first() );
       
   649 
       
   650             /**
       
   651              * All the IAPs that were not found are contained in non_found_iaps_list_m
       
   652              * list. Those that have secondary SSIDs defined, will be moved back to
       
   653              * iap_data_list_m for scanning.
       
   654              */
       
   655 
       
   656             if ( iap_ssid_list_m )
       
   657                 {
       
   658                 core_iap_data_s* iap = non_found_iaps_list_m.first();
       
   659                 while( iap )
       
   660                     {
   638                     {
   661                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - checking IAP ID %u for secondary SSIDs",
   639                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - checking IAP ID %u for secondary SSIDs",
   662                         iap->id );
   640                         entry->id );
   663 
   641 
   664                     if ( is_id_in_secondary_ssid_list( iap->id ) )
   642                     if( !is_iap_in_availability_list(                        
       
   643                             entry->id,
       
   644                             iap_availability_list_m ) &&
       
   645                         is_id_in_secondary_ssid_list(
       
   646                             entry->id ) )
   665                         {
   647                         {
   666                         DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP has secondary SSID(s) defined" );
   648                         DEBUG( "core_operation_get_available_iaps_c::next_state() - IAP has secondary SSID(s) defined" );
   667 
       
   668                         /** Using a temporary pointer to guarantee list iterator working. */
       
   669                         core_iap_data_s* temp = iap;
       
   670                         iap = non_found_iaps_list_m.next();
       
   671 
       
   672                         non_found_iaps_list_m.remove( temp );
       
   673                         iap_data_list_m.append( temp );
       
   674                         }
   649                         }
   675                     else
   650                     else
   676                         {
   651                         {
   677                         iap = non_found_iaps_list_m.next();
   652                         iap_data_iter.remove();
       
   653                         delete entry;
       
   654                         entry = NULL;
   678                         }
   655                         }
   679                     }
   656                     }
   680                 }
   657                 }
   681 
   658 
   682             if ( !iap_data_list_m.count() )
   659             if ( !iap_data_list_m.count() )
   725  
   702  
   726                     if ( is_ssid_in_scanlist(
   703                     if ( is_ssid_in_scanlist(
   727                             entry->ssid,
   704                             entry->ssid,
   728                             client_scan_data_m ) )
   705                             client_scan_data_m ) )
   729                         {                    
   706                         {                    
   730                         direct_scanned_ssid_m = entry->used_ssid;
       
   731 
       
   732                         DEBUG1S( "core_operation_get_available_iaps_c::next_state() - matching SSID found, doing a direct scan for SSID ",
   707                         DEBUG1S( "core_operation_get_available_iaps_c::next_state() - matching SSID found, doing a direct scan for SSID ",
   733                             direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
   708                             entry->used_ssid.length, entry->used_ssid.ssid );
   734 
   709 
   735                         server_m->get_scan_list().set_tag(
   710                         server_m->get_scan_list().set_tag(
   736                             core_scan_list_tag_direct_scan );
   711                             core_scan_list_tag_direct_scan );
   737 
   712 
   738                         const core_scan_channels_s& channels(
   713                         const core_scan_channels_s& channels(
   747                         server_m->register_frame_handler( this );
   722                         server_m->register_frame_handler( this );
   748 
   723 
   749                         drivers_m->scan(
   724                         drivers_m->scan(
   750                             request_id_m,
   725                             request_id_m,
   751                             core_scan_mode_active,
   726                             core_scan_mode_active,
   752                             direct_scanned_ssid_m,
   727                             entry->used_ssid,
   753                             server_m->get_device_settings().scan_rate,
   728                             server_m->get_device_settings().scan_rate,
   754                             channels,
   729                             channels,
   755                             server_m->get_device_settings().active_scan_min_ch_time,
   730                             server_m->get_device_settings().active_scan_min_ch_time,
   756                             server_m->get_device_settings().active_scan_max_ch_time,
   731                             server_m->get_device_settings().active_scan_max_ch_time,
   757                             is_split_scan_m );                    
   732                             is_split_scan_m );                    
   774             DEBUG1( "core_operation_get_available_iaps_c::next_state() - no more entries for IAP ID %u, moving to next IAP",
   749             DEBUG1( "core_operation_get_available_iaps_c::next_state() - no more entries for IAP ID %u, moving to next IAP",
   775                 iap->id );
   750                 iap->id );
   776 
   751 
   777             remove_secondary_ssid_entries_by_id( iap->id );            
   752             remove_secondary_ssid_entries_by_id( iap->id );            
   778             iap_data_list_m.remove( iap );
   753             iap_data_list_m.remove( iap );
   779             non_found_iaps_list_m.append( iap );
   754             delete iap;
       
   755             iap = NULL;
   780             (void)iap_ssid_list_m->first();
   756             (void)iap_ssid_list_m->first();
   781             (void)iap_data_list_m.first();
   757             (void)iap_data_list_m.first();
   782 
   758 
   783             return asynch_goto( core_state_secondary_ssid_next );
   759             return asynch_goto( core_state_secondary_ssid_next );
   784             }
   760             }
   797             ASSERT( entry );
   773             ASSERT( entry );
   798 
   774 
   799             core_scan_list_iterator_by_tag_and_ssid_c iter(
   775             core_scan_list_iterator_by_tag_and_ssid_c iter(
   800                 server_m->get_scan_list(),
   776                 server_m->get_scan_list(),
   801                 core_scan_list_tag_direct_scan,
   777                 core_scan_list_tag_direct_scan,
   802                 direct_scanned_ssid_m );
   778                 entry->used_ssid );
   803 
   779 
   804             for ( core_ap_data_c* ap_data = iter.first(); ap_data; ap_data = iter.next() )
   780             for ( core_ap_data_c* ap_data = iter.first(); ap_data; ap_data = iter.next() )
   805                 {
   781                 {
   806                 core_iap_data_c iap_data( *iap );
   782                 core_iap_data_c iap_data( *iap );
   807                 if ( core_tools_parser_c::is_ap_compatible_with_iap(
   783                 if ( core_tools_parser_c::is_ap_compatible_with_iap(
   813                     false_t ) == core_connect_ok )
   789                     false_t ) == core_connect_ok )
   814                     {
   790                     {
   815                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - secondary SSID match for IAP ID %u",
   791                     DEBUG1( "core_operation_get_available_iaps_c::next_state() - secondary SSID match for IAP ID %u",
   816                         iap->id );
   792                         iap->id );
   817 
   793 
   818                     u32_t* iap_id = new u32_t;
   794                     update_iap_availability(
   819                     if( iap_id )
   795                         iap_data.id(),
   820                         {
   796                         ap_data->rcpi() );
   821                         *iap_id = iap->id;
       
   822                         iap_id_list_m.append( iap_id );
       
   823                         iap_id = NULL;
       
   824                         }
       
   825 
       
   826                     remove_secondary_ssid_entries_by_id( iap->id );
   797                     remove_secondary_ssid_entries_by_id( iap->id );
   827                     iap_data_list_m.remove( iap );
   798                     iap_data_list_m.remove( iap );
   828                     (void)iap_ssid_list_m->first();
   799                     (void)iap_ssid_list_m->first();
   829                     (void)iap_data_list_m.first();
   800                     (void)iap_data_list_m.first();
   830                     
   801                     
   834                     return goto_state( core_state_secondary_ssid_next );
   805                     return goto_state( core_state_secondary_ssid_next );
   835                     }
   806                     }
   836                 }
   807                 }
   837 
   808 
   838             DEBUG1S( "core_operation_get_available_iaps_c::next_state() - no matching SSID ",
   809             DEBUG1S( "core_operation_get_available_iaps_c::next_state() - no matching SSID ",
   839                 direct_scanned_ssid_m.length, direct_scanned_ssid_m.ssid );
   810                 entry->used_ssid.length, entry->used_ssid.ssid );
   840 
   811 
   841             (void)iap_ssid_list_m->next();
   812             (void)iap_ssid_list_m->next();
   842 
   813 
   843             return goto_state( core_state_secondary_ssid_next );
   814             return goto_state( core_state_secondary_ssid_next );
   844             }
   815             }
   852             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list contains %u AP(s)",
   823             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list contains %u AP(s)",
   853                 client_scan_data_m.Count() );
   824                 client_scan_data_m.Count() );
   854             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list size is %u bytes",
   825             DEBUG1( "core_operation_get_available_iaps_c::next_state() - scan list size is %u bytes",
   855                 client_scan_data_m.Size() );
   826                 client_scan_data_m.Size() );
   856             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) found",
   827             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) found",
   857                 iap_id_list_m.count() );
   828                 iap_availability_list_m.count() );
   858             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) not found",
   829             DEBUG1( "core_operation_get_available_iaps_c::next_state() - %u IAP(s) not found",
   859                 non_found_iaps_list_m.count() );
   830                 iap_data_count_m - iap_availability_list_m.count() );
   860 
   831 
   861             /**
   832             /**
   862              * Detect channels that have APs with long beacon intervals.
   833              * Detect channels that have APs with long beacon intervals.
   863              */
   834              */
   864             const u32_t long_beacon_interval(
   835             const u32_t long_beacon_interval(
   948     }
   919     }
   949 
   920 
   950 // ---------------------------------------------------------------------------
   921 // ---------------------------------------------------------------------------
   951 // ---------------------------------------------------------------------------
   922 // ---------------------------------------------------------------------------
   952 //
   923 //
   953 void core_operation_get_available_iaps_c::remove_non_hidden_iaps()
       
   954     {
       
   955     DEBUG("core_operation_get_available_iaps_c::remove_non_hidden_iaps()");
       
   956 
       
   957     core_iap_data_s* iap = iap_data_list_m.first();
       
   958     while( iap )
       
   959         {
       
   960         if( !iap->is_hidden )
       
   961             {
       
   962             DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - removing IAP ID %u",
       
   963                 iap->id );
       
   964             
       
   965             core_iap_data_s* temp = iap;
       
   966             iap = iap_data_list_m.next();
       
   967             core_error_e ret = iap_data_list_m.remove( temp );
       
   968             if( ret != core_error_ok )
       
   969                 {
       
   970                 DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - error while removing IAP entry (%d)",
       
   971                     ret );
       
   972                 }
       
   973             non_found_iaps_list_m.append( temp );
       
   974             }
       
   975         else
       
   976             {
       
   977             DEBUG1("core_operation_get_available_iaps_c::remove_non_hidden_iaps() - leaving IAP ID %u",
       
   978                 iap->id );
       
   979 
       
   980             iap = iap_data_list_m.next();
       
   981             }
       
   982         }
       
   983     }
       
   984 
       
   985 // ---------------------------------------------------------------------------
       
   986 // ---------------------------------------------------------------------------
       
   987 //
       
   988 void core_operation_get_available_iaps_c::process_scan_results(
   924 void core_operation_get_available_iaps_c::process_scan_results(
   989     u8_t tag )
   925     u8_t tag )
   990     {
   926     {
   991     DEBUG( "core_operation_get_available_iaps_c::process_scan_results()" );
   927     DEBUG( "core_operation_get_available_iaps_c::process_scan_results()" );
   992 
   928 
  1005 //
   941 //
  1006 void core_operation_get_available_iaps_c::remove_matching_iaps(
   942 void core_operation_get_available_iaps_c::remove_matching_iaps(
  1007     core_ap_data_c& ap_data )
   943     core_ap_data_c& ap_data )
  1008     {
   944     {
  1009     DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps()" );
   945     DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps()" );
  1010         
   946 
  1011     if ( ap_data.rcpi() < server_m->get_device_settings().iap_availability_rcpi_threshold )
   947     core_mac_address_s bssid = ap_data.bssid();
  1012         {
   948 
  1013         DEBUG2( "core_operation_get_available_iaps_c::remove_matching_iaps() - AP not considered, signal too weak (%u vs %u)",
       
  1014             ap_data.rcpi(), server_m->get_device_settings().iap_availability_rcpi_threshold );
       
  1015 
       
  1016         return;
       
  1017         }
       
  1018     
       
  1019     u8_t treshold_val = 
       
  1020         static_cast<u8_t>(server_m->get_core_settings().rcp_improve_boundary());
       
  1021         
       
  1022     /**
   949     /**
  1023      * Loop through the IAP list.
   950      * Loop through the list of IAPs.
  1024      */
   951      */
  1025     core_iap_data_s* iap = iap_data_list_m.first();
   952     core_type_list_iterator_c<core_iap_data_s> iap_data_iter( iap_data_list_m );
  1026     while( iap )
   953     for( core_iap_data_s* entry = iap_data_iter.first(); entry; entry = iap_data_iter.next() )
  1027         {
   954         {
  1028         core_iap_data_c iap_data( *iap );
   955         core_iap_data_c iap_data( *entry );
  1029         if ( iap->ssid == ap_data.ssid() &&
   956         if ( iap_data.ssid() == ap_data.ssid() &&
  1030              core_tools_parser_c::is_ap_compatible_with_iap(
   957              core_tools_parser_c::is_ap_compatible_with_iap(
  1031                 server_m->get_wpx_adaptation_instance(),
   958                 server_m->get_wpx_adaptation_instance(),
  1032                 ap_data,
   959                 ap_data,
  1033                 iap_data,
   960                 iap_data,
  1034                 server_m->get_core_settings(),
   961                 server_m->get_core_settings(),
  1035                 false_t,
   962                 false_t,
  1036                 false_t ) == core_connect_ok )
   963                 false_t ) == core_connect_ok )
  1037             {
   964             {
  1038             DEBUG1("core_operation_get_available_iaps_c::remove_matching_iaps() - match found for IAP ID %u",
   965             DEBUG7("core_operation_get_available_iaps_c::remove_matching_iaps() - BSSID %02X:%02X:%02X:%02X:%02X:%02X matches IAP ID %u",
  1039                 iap->id );            
   966                 bssid.addr[0], bssid.addr[1], bssid.addr[2], 
  1040 
   967                 bssid.addr[3], bssid.addr[4], bssid.addr[5], 
  1041             u32_t* iap_id = new u32_t;
   968                 iap_data.id() );
  1042             if( iap_id )
   969 
  1043                 {
   970             update_iap_availability(
  1044                 if ( server_m->get_core_settings().is_iap_id_in_weak_list( iap->id) ) 
   971                 iap_data.id(),
  1045                     {
   972                 ap_data.rcpi() ); 
  1046                     DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps() - IAP ID is in weak list" );
       
  1047                     
       
  1048                     if ( ap_data.rcpi() > treshold_val )
       
  1049                         {
       
  1050                         DEBUG( "core_operation_get_available_iaps_c::remove_matching_iaps() - RCPI improved enough, remove IAP ID from weak list" );
       
  1051                         *iap_id = iap->id;
       
  1052                         iap_id_list_m.append( iap_id );
       
  1053             		    iap_id = NULL;
       
  1054                         
       
  1055                         server_m->get_core_settings().remove_iap_id_from_weak_list( iap->id );
       
  1056                         }
       
  1057 
       
  1058                     }
       
  1059                 else
       
  1060                     {
       
  1061                     *iap_id = iap->id;
       
  1062                     iap_id_list_m.append( iap_id );
       
  1063                     iap_id = NULL;
       
  1064                     }
       
  1065                 }
       
  1066 
       
  1067             /** Using a temporary pointer to guarantee list iterator working. */
       
  1068             core_iap_data_s* temp = iap;
       
  1069             
       
  1070             iap = iap_data_list_m.next();
       
  1071             core_error_e ret = iap_data_list_m.remove( temp );
       
  1072             if( ret != core_error_ok )
       
  1073                 {
       
  1074                 if( iap )
       
  1075                     {
       
  1076                     DEBUG1("core_operation_get_available_iaps_c::remove_matching_iaps() - error while removing IAP entry (%d)",
       
  1077                         iap->id );                   
       
  1078                     }
       
  1079                 }
       
  1080 
       
  1081             delete temp;
       
  1082             temp = NULL;
       
  1083             delete iap_id;
       
  1084             iap_id = NULL;
       
  1085             }
       
  1086         else
       
  1087             {
       
  1088             iap = iap_data_list_m.next();
       
  1089             }
   973             }
  1090         }
   974         }
  1091     }
   975     }
  1092 
   976 
  1093 // ---------------------------------------------------------------------------
   977 // ---------------------------------------------------------------------------
  1225                 }
  1109                 }
  1226             }
  1110             }
  1227         }
  1111         }
  1228 
  1112 
  1229     return false_t;
  1113     return false_t;
       
  1114     }
       
  1115 
       
  1116 // ---------------------------------------------------------------------------
       
  1117 // ---------------------------------------------------------------------------
       
  1118 //
       
  1119 bool_t core_operation_get_available_iaps_c::is_ssid_in_list(
       
  1120     const core_ssid_s& ssid,
       
  1121     core_type_list_c<core_ssid_s>& ssid_list ) const
       
  1122     {
       
  1123     core_type_list_iterator_c<core_ssid_s> ssid_iter( ssid_list );
       
  1124     for( core_ssid_s* entry = ssid_iter.first(); entry; entry = ssid_iter.next() )
       
  1125         {
       
  1126         if( *entry == ssid )
       
  1127             {
       
  1128             return true_t;
       
  1129             }
       
  1130         }
       
  1131 
       
  1132     return false_t;
       
  1133     }
       
  1134 
       
  1135 // ---------------------------------------------------------------------------
       
  1136 // ---------------------------------------------------------------------------
       
  1137 //
       
  1138 bool_t core_operation_get_available_iaps_c::is_iap_in_availability_list(
       
  1139     u32_t iap_id,
       
  1140     core_type_list_c<core_iap_availability_data_s>& iap_list ) const
       
  1141     {
       
  1142     core_type_list_iterator_c<core_iap_availability_data_s> iap_iter( iap_list );
       
  1143     for( core_iap_availability_data_s* entry = iap_iter.first(); entry; entry = iap_iter.next() )
       
  1144         {
       
  1145         if( entry->id == iap_id )
       
  1146             {
       
  1147             return true_t;
       
  1148             }
       
  1149         }
       
  1150 
       
  1151     return false_t;
       
  1152     }
       
  1153 
       
  1154 // ---------------------------------------------------------------------------
       
  1155 // ---------------------------------------------------------------------------
       
  1156 //
       
  1157 void core_operation_get_available_iaps_c::update_iap_availability(
       
  1158     u32_t iap_id,
       
  1159     u8_t iap_rcpi )
       
  1160     {
       
  1161     core_type_list_iterator_c<core_iap_availability_data_s> iap_iter( iap_availability_list_m );
       
  1162     bool_t is_found( false_t );
       
  1163     core_iap_availability_data_s* entry = iap_iter.first();
       
  1164     while( entry && !is_found )
       
  1165         {
       
  1166         if( entry->id == iap_id )
       
  1167             {
       
  1168             is_found = true_t;
       
  1169             if( entry->rcpi < iap_rcpi )
       
  1170                 {
       
  1171                 DEBUG3("core_operation_get_available_iaps_c::update_iap_availability() - IAP %u already available, RCPI improved from %u to %u",
       
  1172                     iap_id, entry->rcpi, iap_rcpi );
       
  1173 
       
  1174                 entry->rcpi = iap_rcpi;
       
  1175                 }
       
  1176             else
       
  1177                 {
       
  1178                 DEBUG3("core_operation_get_available_iaps_c::update_iap_availability() - IAP %u already available, RCPI not improved (%u vs %u)",
       
  1179                     iap_id, iap_rcpi, entry->rcpi );            
       
  1180                 }
       
  1181             }
       
  1182 
       
  1183         entry = iap_iter.next();
       
  1184         }
       
  1185 
       
  1186     if( !is_found )
       
  1187         {
       
  1188         core_iap_availability_data_s* data = new core_iap_availability_data_s;
       
  1189         if( data )        
       
  1190             {
       
  1191             DEBUG2("core_operation_get_available_iaps_c::update_iap_availability() - IAP %u marked as available, RCPI is %u",
       
  1192                 iap_id, iap_rcpi );
       
  1193 
       
  1194             data->id = iap_id;
       
  1195             data->rcpi = iap_rcpi;
       
  1196             core_error_e ret = iap_availability_list_m.append( data );
       
  1197             if( ret != core_error_ok )
       
  1198                 {
       
  1199                 delete data;
       
  1200                 }
       
  1201             data = NULL;
       
  1202             }
       
  1203         }
  1230     }
  1204     }
  1231 
  1205 
  1232 // ---------------------------------------------------------------------------
  1206 // ---------------------------------------------------------------------------
  1233 // ---------------------------------------------------------------------------
  1207 // ---------------------------------------------------------------------------
  1234 //    
  1208 //