wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_server.cpp
changeset 0 c40eb8fe8501
child 10 0abc8c98be24
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Main class for core server
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 89 %
       
    20 */
       
    21 
       
    22 #include "core_server.h"
       
    23 #include "abs_core_server_callback.h"
       
    24 #include "abs_core_driverif.h"
       
    25 #include "abs_core_timer.h"
       
    26 #include "abs_core_frame_handler.h"
       
    27 #include "abs_core_event_handler.h"
       
    28 #include "core_timer_factory.h"
       
    29 #include "core_operation_connect.h"
       
    30 #include "core_operation_update_device_settings.h"
       
    31 #include "core_operation_scan.h"
       
    32 #include "core_operation_get_available_iaps.h"
       
    33 #include "core_operation_release.h"
       
    34 #include "core_operation_unload_drivers.h"
       
    35 #include "core_operation_check_rcpi.h"
       
    36 #include "core_operation_handle_frame.h"
       
    37 #include "core_operation_null.h"
       
    38 #include "core_operation_get_rcpi.h"
       
    39 #include "core_operation_configure_multicast_group.h"
       
    40 #include "core_operation_update_power_mode.h"
       
    41 #include "core_operation_update_rxtx_parameters.h"
       
    42 #include "core_operation_get_statistics.h"
       
    43 #include "core_operation_set_uapsd_settings.h"
       
    44 #include "core_operation_set_power_save_settings.h"
       
    45 #include "core_operation_protected_setup.h"
       
    46 #include "core_operation_create_ts.h"
       
    47 #include "core_operation_delete_ts.h"
       
    48 #include "core_operation_power_save_test.h"
       
    49 #include "core_operation_set_arp_filter.h"
       
    50 #include "core_operation_directed_roam.h"
       
    51 #include "core_frame_ethernet.h"
       
    52 #include "core_connection_data.h"
       
    53 #include "core_eapol_handler.h"
       
    54 #include "core_frame_dot11.h"
       
    55 #include "core_frame_echo_test.h"
       
    56 #include "am_debug.h"
       
    57 #include "core_callback.h"
       
    58 #include "core_tools.h"
       
    59 #include "core_tools_parser.h"
       
    60 #include "core_wpx_adaptation_factory.h"
       
    61 #include "core_traffic_stream_list_iter.h"
       
    62 
       
    63 // ======== MEMBER FUNCTIONS ========
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 core_server_c::core_server_c(
       
    69     abs_core_server_callback_c& callback,
       
    70     abs_core_driverif_c& drivers,
       
    71     const core_device_settings_s& settings,
       
    72     const core_mac_address_s& mac_address,
       
    73     u32_t features ) :
       
    74     callback_m( callback ),
       
    75     drivers_m( drivers ),
       
    76     device_settings_m( settings ),
       
    77     queue_m( ),
       
    78     queue_timer_m( NULL ),
       
    79     driver_unload_timer_m( NULL ),
       
    80     core_settings_m( features ),
       
    81     connection_data_m( NULL ),
       
    82     own_mac_addr_m( mac_address ),
       
    83     eapol_handler_m( NULL ),
       
    84     eapol_m( NULL ),
       
    85     cm_timer_m( ),
       
    86     roam_timer_m( NULL ),
       
    87     operation_timer_m( NULL ),
       
    88     driver_dhcp_timer_m( NULL ),
       
    89     frame_handler_m( NULL ),
       
    90     event_handler_m( NULL ),
       
    91     scan_list_m( ),
       
    92     wpx_adaptation_m( NULL )
       
    93     {
       
    94     DEBUG( "core_server_c::core_server_c()" );
       
    95     queue_m.clear();
       
    96     }
       
    97 
       
    98 // ---------------------------------------------------------------------------
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 core_server_c::~core_server_c()
       
   102     {
       
   103     DEBUG( "core_server_c::~core_server_c()" );
       
   104 
       
   105     queue_m.clear();
       
   106     delete connection_data_m;
       
   107 
       
   108     if ( queue_timer_m )
       
   109         {
       
   110         queue_timer_m->stop();
       
   111         core_timer_factory_c::destroy_timer( queue_timer_m );
       
   112         queue_timer_m = NULL;
       
   113         }
       
   114     if ( driver_unload_timer_m )
       
   115         {
       
   116         driver_unload_timer_m->stop();
       
   117         core_timer_factory_c::destroy_timer( driver_unload_timer_m );
       
   118         driver_unload_timer_m = NULL;
       
   119         }
       
   120     if ( roam_timer_m )
       
   121         {
       
   122         roam_timer_m->stop();
       
   123         core_timer_factory_c::destroy_timer( roam_timer_m );
       
   124         roam_timer_m = NULL;
       
   125         }
       
   126     if ( operation_timer_m )
       
   127         {
       
   128         operation_timer_m->stop();
       
   129         core_timer_factory_c::destroy_timer( operation_timer_m );
       
   130         operation_timer_m = NULL;
       
   131         }
       
   132     if ( driver_dhcp_timer_m )
       
   133         {
       
   134         driver_dhcp_timer_m->stop();
       
   135         core_timer_factory_c::destroy_timer( driver_dhcp_timer_m );
       
   136         driver_dhcp_timer_m = NULL;
       
   137         }
       
   138     if ( eapol_m )
       
   139         {
       
   140         eapol_m->shutdown();
       
   141         delete eapol_m;
       
   142         }
       
   143     delete wpx_adaptation_m;
       
   144     delete eapol_handler_m;
       
   145     frame_handler_m = NULL;
       
   146     event_handler_m = NULL;
       
   147     }
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // ---------------------------------------------------------------------------
       
   151 //
       
   152 core_error_e core_server_c::init()
       
   153     {
       
   154     DEBUG( "core_server_c::init()" );
       
   155 
       
   156     drivers_m.init( this );
       
   157 
       
   158     core_callback_c* queue_timer_callback = 
       
   159         new core_callback_c( &(core_server_c::queue_timer_expired), this );
       
   160     if( !queue_timer_callback )
       
   161         {
       
   162         DEBUG("ERROR creating callback object");
       
   163         return core_error_no_memory;
       
   164         }
       
   165     queue_timer_m = core_timer_factory_c::create_timer( queue_timer_callback );
       
   166     if( !queue_timer_m )
       
   167         {
       
   168         DEBUG( "ERROR creating timer" );
       
   169         delete queue_timer_callback;
       
   170         return core_error_no_memory;
       
   171         }
       
   172 
       
   173     core_callback_c* unload_timer_callback = 
       
   174         new core_callback_c( &(core_server_c::unload_timer_expired), this );
       
   175     if( !unload_timer_callback )
       
   176         {
       
   177         DEBUG("ERROR creating callback object");
       
   178         return core_error_no_memory;
       
   179         }
       
   180     driver_unload_timer_m = core_timer_factory_c::create_timer( unload_timer_callback );
       
   181     if( !driver_unload_timer_m )
       
   182         {
       
   183         DEBUG( "ERROR creating timer" );
       
   184         delete unload_timer_callback;
       
   185         return core_error_no_memory;
       
   186         }
       
   187     
       
   188     core_callback_c* roam_timer_callback = 
       
   189         new core_callback_c( &(core_server_c::roam_timer_expired), this );
       
   190     if( !roam_timer_callback )
       
   191         {
       
   192         DEBUG("ERROR creating callback object");
       
   193         return core_error_no_memory;
       
   194         }
       
   195     roam_timer_m = core_timer_factory_c::create_timer( roam_timer_callback );
       
   196     if( !roam_timer_m )
       
   197         {
       
   198         DEBUG( "ERROR creating timer" );
       
   199         delete roam_timer_callback;
       
   200         return core_error_no_memory;
       
   201         } 
       
   202 
       
   203     core_callback_c* operation_timer_callback = 
       
   204         new core_callback_c( &(core_server_c::operation_timer_expired), this );
       
   205     if( !operation_timer_callback )
       
   206         {
       
   207         DEBUG("ERROR creating callback object");
       
   208         return core_error_no_memory;
       
   209         }
       
   210     operation_timer_m = core_timer_factory_c::create_timer( operation_timer_callback );
       
   211     if( !operation_timer_m )
       
   212         {
       
   213         DEBUG( "ERROR creating timer" );
       
   214         delete operation_timer_callback;
       
   215         return core_error_no_memory;
       
   216         } 
       
   217 
       
   218     core_callback_c* dhcp_timer_callback = 
       
   219         new core_callback_c( &(core_server_c::dhcp_timer_expired), this );
       
   220     if( !dhcp_timer_callback )
       
   221         {
       
   222         DEBUG("ERROR creating callback object");
       
   223         return core_error_no_memory;
       
   224         }        
       
   225     driver_dhcp_timer_m = core_timer_factory_c::create_timer( dhcp_timer_callback );
       
   226     if( !driver_dhcp_timer_m )
       
   227         {
       
   228         DEBUG( "ERROR creating timer" );
       
   229         delete dhcp_timer_callback;
       
   230         return core_error_no_memory;
       
   231         } 
       
   232 
       
   233     wpx_adaptation_m = core_wpx_adaptation_factory_c::instance(
       
   234         this, &drivers_m, &callback_m );
       
   235     if ( !wpx_adaptation_m )
       
   236         {
       
   237         DEBUG("ERROR creating WPX adaptation");
       
   238         return core_error_no_memory;
       
   239         }
       
   240 
       
   241     eapol_handler_m = new core_eapol_handler_c(
       
   242         this, &drivers_m, &callback_m );
       
   243     if ( !eapol_handler_m )
       
   244         {
       
   245         DEBUG("ERROR creating eapol handler");
       
   246         return core_error_no_memory;
       
   247         }
       
   248 
       
   249     core_settings_m.set_rcpi_boundaries(
       
   250         device_settings_m.rcpi_trigger,
       
   251         device_settings_m.rcpi_trigger + device_settings_m.rcpi_difference );
       
   252 
       
   253     return core_error_ok;
       
   254     }
       
   255 
       
   256 // ---------------------------------------------------------------------------
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 core_device_settings_s& core_server_c::get_device_settings()
       
   260     {
       
   261     return device_settings_m;
       
   262     }
       
   263 
       
   264 // ---------------------------------------------------------------------------
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 core_settings_c& core_server_c::get_core_settings()
       
   268     {
       
   269     return core_settings_m;
       
   270     }
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // ---------------------------------------------------------------------------
       
   274 //
       
   275 core_connection_data_c* core_server_c::get_connection_data()
       
   276     {
       
   277     return connection_data_m;
       
   278     }
       
   279 
       
   280 // ---------------------------------------------------------------------------
       
   281 // ---------------------------------------------------------------------------
       
   282 //
       
   283 core_wlan_eapol_interface_c& core_server_c::get_eapol_instance()
       
   284     {
       
   285     return *eapol_m;
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------
       
   289 // ---------------------------------------------------------------------------
       
   290 //
       
   291 void core_server_c::set_eapol_handler(
       
   292     abs_wlan_eapol_callback_interface_c* handler )
       
   293     {
       
   294     eapol_handler_m->set_eapol_handler( handler );
       
   295     }
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 core_mac_address_s& core_server_c::own_mac_addr()
       
   301     {
       
   302     return own_mac_addr_m;
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------------------------
       
   306 // ---------------------------------------------------------------------------
       
   307 //
       
   308 core_error_e core_server_c::queue_int_operation(
       
   309     core_operation_base_c* operation )
       
   310     {
       
   311     DEBUG( "core_server_c::queue_int_operation()" );
       
   312 
       
   313     if ( !operation )
       
   314         {
       
   315         DEBUG( "core_server_c::queue_int_operation() - no operation" );
       
   316 
       
   317         return core_error_no_memory;
       
   318         }
       
   319     else if ( operation->is_flags( core_operation_base_c::core_base_flag_only_one_instance ) &&
       
   320         is_operation_in_queue_with_type( operation->operation_type() ) )
       
   321         {
       
   322         DEBUG( "core_server_c::queue_int_operation() - only one instance allowed in the operation queue" );
       
   323 
       
   324         delete operation;
       
   325         operation = NULL;
       
   326 
       
   327         return core_error_already_exists;
       
   328         }
       
   329     else
       
   330         {
       
   331         core_error_e ret = queue_m.append( operation );
       
   332         if ( ret != core_error_ok )
       
   333             {
       
   334             DEBUG1( "core_server_c::queue_int_operation() - unable to queue the request (%u)",
       
   335                 ret );
       
   336 
       
   337             delete operation;
       
   338             operation = NULL;
       
   339 
       
   340             return ret;
       
   341             }
       
   342         }
       
   343 
       
   344     return core_error_ok;    
       
   345     }
       
   346 
       
   347 // ---------------------------------------------------------------------------
       
   348 // ---------------------------------------------------------------------------
       
   349 //
       
   350 core_error_e core_server_c::queue_int_operation_and_run_next(
       
   351     core_operation_base_c* operation )
       
   352     {
       
   353     DEBUG( "core_server_c::queue_int_operation_and_run_next()" );
       
   354 
       
   355     core_error_e ret = queue_int_operation( operation );
       
   356     if ( ret != core_error_ok )
       
   357         {
       
   358         return ret;
       
   359         }
       
   360 
       
   361     schedule_operation();
       
   362 
       
   363     return core_error_ok;
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // ---------------------------------------------------------------------------
       
   368 //
       
   369 core_error_e core_server_c::init_connection_data(
       
   370     const core_iap_data_s& iap_data,
       
   371     const core_device_settings_s& device_settings )
       
   372     {
       
   373     connection_data_m = new core_connection_data_c( iap_data, device_settings );
       
   374 
       
   375     if ( !connection_data_m )
       
   376         {
       
   377         return core_error_no_memory;
       
   378         }
       
   379 
       
   380     return core_error_ok;
       
   381     }
       
   382    
       
   383 // ---------------------------------------------------------------------------
       
   384 // ---------------------------------------------------------------------------
       
   385 //    
       
   386 void core_server_c::clear_connection_data()
       
   387     {
       
   388     DEBUG( "core_server_c::clear_connection_data()" );
       
   389     
       
   390     delete connection_data_m;
       
   391     connection_data_m = NULL;
       
   392     }
       
   393 
       
   394 // ---------------------------------------------------------------------------
       
   395 // ---------------------------------------------------------------------------
       
   396 //
       
   397 void core_server_c::schedule_roam_timer(
       
   398     u32_t delay )
       
   399     {
       
   400     DEBUG1( "core_server_c::schedule_roam_timer() - delay %u",
       
   401         delay );
       
   402 
       
   403     ASSERT( !roam_timer_m->is_active() );
       
   404 
       
   405     roam_timer_m->start(
       
   406         delay );    
       
   407     }
       
   408 
       
   409 // ---------------------------------------------------------------------------
       
   410 // ---------------------------------------------------------------------------
       
   411 //
       
   412 void core_server_c::cancel_roam_timer()
       
   413     {
       
   414     DEBUG( "core_server_c::cancel_roam_timer()" );
       
   415     
       
   416     roam_timer_m->stop();
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // ---------------------------------------------------------------------------
       
   421 //    
       
   422 void core_server_c::roam_timer_expired(
       
   423     void* this_ptr )
       
   424     {
       
   425     DEBUG("core_server_c::roam_timer_expired()");
       
   426     core_server_c* self = static_cast<core_server_c*>( this_ptr );
       
   427 
       
   428     // send an indication to adaptation
       
   429     self->callback_m.notify(
       
   430         core_notification_rcpi_roam_attempt_started,
       
   431         0, 
       
   432         NULL );
       
   433     
       
   434     core_operation_base_c* command = new core_operation_check_rcpi_c(
       
   435         REQUEST_ID_CORE_INTERNAL,
       
   436         self,
       
   437         &(self->drivers_m),
       
   438         &(self->callback_m),
       
   439         core_operation_check_rcpi_c::core_rcpi_check_reason_timer );
       
   440 
       
   441     self->queue_int_operation_and_run_next( command );
       
   442     }
       
   443 
       
   444 // ---------------------------------------------------------------------------
       
   445 // ---------------------------------------------------------------------------
       
   446 //
       
   447 void core_server_c::schedule_operation_timer(
       
   448     u32_t delay )
       
   449     {
       
   450     DEBUG1( "core_server_c::schedule_operation_timer() - delay %u",
       
   451         delay );
       
   452 
       
   453     ASSERT( !operation_timer_m->is_active() );
       
   454     operation_timer_m->start(
       
   455         delay );    
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 void core_server_c::cancel_operation_timer()
       
   462     {
       
   463     DEBUG( "core_server_c::cancel_operation_timer()" );
       
   464     operation_timer_m->stop();
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // ---------------------------------------------------------------------------
       
   469 //    
       
   470 void core_server_c::operation_timer_expired(
       
   471     void* this_ptr )
       
   472     {
       
   473     DEBUG("core_server_c::operation_timer_expired()");
       
   474     core_server_c* self = static_cast<core_server_c*>( this_ptr );
       
   475 
       
   476     core_operation_base_c* command = self->queue_m.first();
       
   477     ASSERT( command );
       
   478     ASSERT( command->is_executing() );
       
   479     self->request_complete( command->request_id(), core_error_ok );
       
   480     }
       
   481 
       
   482 // ---------------------------------------------------------------------------
       
   483 // ---------------------------------------------------------------------------
       
   484 //
       
   485 bool_t core_server_c::is_operation_in_queue_with_flags(
       
   486     u32_t feature_flags )
       
   487     {
       
   488     core_type_list_iterator_c<core_operation_base_c> iter( queue_m );
       
   489     for( core_operation_base_c* current = iter.first(); current; current = iter.next() )
       
   490         {
       
   491         if ( current->is_flags( feature_flags ) )
       
   492             {
       
   493             return true_t;
       
   494             }
       
   495         }
       
   496 
       
   497     return false_t;    
       
   498     }
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 // ---------------------------------------------------------------------------
       
   502 //
       
   503 bool_t core_server_c::is_operation_in_queue_with_type(
       
   504     u32_t type )
       
   505     {
       
   506     core_type_list_iterator_c<core_operation_base_c> iter( queue_m );
       
   507     for( core_operation_base_c* current = iter.first(); current; current = iter.next() )
       
   508         {
       
   509         if ( current->operation_type() == type )
       
   510             {
       
   511             return true_t;
       
   512             }
       
   513         }
       
   514 
       
   515     return false_t;    
       
   516     }
       
   517 
       
   518 // ---------------------------------------------------------------------------
       
   519 // ---------------------------------------------------------------------------
       
   520 //
       
   521 bool_t core_server_c::is_dhcp_timer_active()
       
   522     {
       
   523     return driver_dhcp_timer_m->is_active();
       
   524     }
       
   525 
       
   526 // ---------------------------------------------------------------------------
       
   527 // ---------------------------------------------------------------------------
       
   528 //
       
   529 void core_server_c::schedule_dhcp_timer(
       
   530     u32_t delay )
       
   531     {
       
   532     DEBUG1( "core_server_c::schedule_dhcp_timer() - delay %u",
       
   533         delay );
       
   534 
       
   535     ASSERT( !is_dhcp_timer_active() );
       
   536 
       
   537     driver_dhcp_timer_m->start(
       
   538         delay );    
       
   539     }
       
   540 
       
   541 // ---------------------------------------------------------------------------
       
   542 // ---------------------------------------------------------------------------
       
   543 //
       
   544 void core_server_c::cancel_dhcp_timer()
       
   545     {
       
   546     DEBUG( "core_server_c::cancel_dhcp_timer()" );
       
   547     
       
   548     driver_dhcp_timer_m->stop();
       
   549     }
       
   550 
       
   551 // ---------------------------------------------------------------------------
       
   552 // ---------------------------------------------------------------------------
       
   553 //
       
   554 void core_server_c::dhcp_timer_expired(
       
   555     void* this_ptr )
       
   556     {
       
   557     DEBUG( "core_server_c::dhcp_timer_expired()" );
       
   558 
       
   559     core_server_c* self = static_cast<core_server_c*>( this_ptr );
       
   560 
       
   561     core_operation_base_c* command = new core_operation_power_save_test_c(
       
   562         REQUEST_ID_CORE_INTERNAL,
       
   563         self,
       
   564         &(self->drivers_m),
       
   565         &(self->callback_m) );        
       
   566 
       
   567     self->queue_int_operation_and_run_next( command );
       
   568     }
       
   569 
       
   570 // ---------------------------------------------------------------------------
       
   571 // ---------------------------------------------------------------------------
       
   572 //
       
   573 void core_server_c::schedule_unload_timer(
       
   574     u32_t delay )
       
   575     {
       
   576     DEBUG1( "core_server_c::schedule_unload_timer() - delay %u",
       
   577         delay );
       
   578 
       
   579     ASSERT( !driver_unload_timer_m->is_active() );
       
   580 
       
   581     driver_unload_timer_m->start(
       
   582         delay );    
       
   583     }
       
   584 
       
   585 // ---------------------------------------------------------------------------
       
   586 // ---------------------------------------------------------------------------
       
   587 //
       
   588 void core_server_c::cancel_unload_timer()
       
   589     {
       
   590     DEBUG( "core_server_c::cancel_unload_timer()" );
       
   591 
       
   592     driver_unload_timer_m->stop();
       
   593     }
       
   594 
       
   595 // ---------------------------------------------------------------------------
       
   596 // ---------------------------------------------------------------------------
       
   597 //
       
   598 void core_server_c::cancel_operations_with_flags(
       
   599     u32_t feature_flags )
       
   600     {
       
   601     DEBUG( "core_server_c::cancel_operations_with_flags()" );
       
   602     DEBUG1( "core_server_c::cancel_operations_with_flags() - feature_flags %u",
       
   603         feature_flags );
       
   604 
       
   605     core_operation_base_c* command = queue_m.first();
       
   606     while ( command )
       
   607         {
       
   608         if ( !command->is_executing() &&
       
   609              command->is_flags( feature_flags ) )
       
   610             {
       
   611             DEBUG2( "core_server_c::cancel_operations_with_flags() - canceling operation (id %u, type %u)",
       
   612                 command->request_id(), command->operation_type() );
       
   613             if ( command->request_id() != REQUEST_ID_CORE_INTERNAL )
       
   614                 {
       
   615                 DEBUG( "core_server_c::cancel_operations_with_flags() - adaptation request, completing it" );
       
   616                 callback_m.request_complete(
       
   617                     command->request_id(),
       
   618                     core_error_cancel );
       
   619                 }
       
   620 
       
   621             queue_m.remove( command );
       
   622             delete command;
       
   623             command = queue_m.first();
       
   624             }
       
   625         else
       
   626             {
       
   627             command = queue_m.next();
       
   628             }        
       
   629         }
       
   630     }
       
   631 
       
   632 // ---------------------------------------------------------------------------
       
   633 // ---------------------------------------------------------------------------
       
   634 //
       
   635 void core_server_c::cancel_operations_with_type(
       
   636     u32_t type )
       
   637     {
       
   638     DEBUG( "core_server_c::cancel_operation_with_type()" );
       
   639     DEBUG1( "core_server_c::cancel_operation_with_type() - type %u",
       
   640         type );
       
   641 
       
   642     core_operation_base_c* command = queue_m.first();
       
   643     while ( command )
       
   644         {
       
   645         if ( !command->is_executing() &&
       
   646              command->operation_type() == type )
       
   647             {
       
   648             DEBUG2( "core_server_c::cancel_operation_with_type() - canceling operation (id %u, type %u)",
       
   649                 command->request_id(), command->operation_type() );
       
   650             if ( command->request_id() != REQUEST_ID_CORE_INTERNAL )
       
   651                 {
       
   652                 DEBUG( "core_server_c::cancel_operation_with_type() - adaptation request, completing it" );
       
   653                 callback_m.request_complete(
       
   654                     command->request_id(),
       
   655                     core_error_cancel );
       
   656                 }
       
   657 
       
   658             queue_m.remove( command );
       
   659             delete command;
       
   660             command = queue_m.first();
       
   661             }
       
   662         else
       
   663             {
       
   664             command = queue_m.next();
       
   665             }
       
   666         }       
       
   667     }
       
   668 
       
   669 // ---------------------------------------------------------------------------
       
   670 // ---------------------------------------------------------------------------
       
   671 //
       
   672 void core_server_c::cancel_all_operations(
       
   673     bool_t is_graceful_cancel )
       
   674     {
       
   675     DEBUG( "core_server_c::cancel_all_operations()" );
       
   676 
       
   677     core_operation_base_c* command = queue_m.first();
       
   678     while ( command )
       
   679         {
       
   680         if ( !command->is_executing() )
       
   681             {
       
   682             DEBUG2( "core_server_c::cancel_all_operations() - canceling operation (id %u, type %u)",
       
   683                 command->request_id(), command->operation_type() );
       
   684             if ( command->request_id() != REQUEST_ID_CORE_INTERNAL )
       
   685                 {
       
   686                 DEBUG( "core_server_c::cancel_all_operations() - adaptation request, completing it" );
       
   687                 callback_m.request_complete(
       
   688                     command->request_id(),
       
   689                     core_error_cancel );
       
   690                 }
       
   691 
       
   692             queue_m.remove( command );
       
   693             delete command;
       
   694             command = queue_m.first();
       
   695             }
       
   696         else
       
   697             {
       
   698             command = queue_m.next();
       
   699             }
       
   700         }
       
   701 
       
   702     command = queue_m.first();
       
   703     if ( command )
       
   704         {
       
   705         if( is_graceful_cancel )
       
   706             {
       
   707             DEBUG2( "core_server_c::cancel_all_operations() - canceling currently executing operation (id %u, type %u) (graceful cancel)",
       
   708                 command->request_id(), command->operation_type() );
       
   709             }
       
   710         else
       
   711             {
       
   712             DEBUG2( "core_server_c::cancel_all_operations() - canceling currently executing operation (id %u, type %u) (forced cancel)",
       
   713                 command->request_id(), command->operation_type() );
       
   714             }
       
   715 
       
   716         ASSERT( command->is_executing() );
       
   717 
       
   718         // Let operation handle it's own cancelling
       
   719         command->user_cancel_operation( is_graceful_cancel );
       
   720         }   
       
   721     }
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // ---------------------------------------------------------------------------
       
   725 //
       
   726 bool_t core_server_c::create_eapol_instance(
       
   727     core_eapol_operating_mode_e mode )
       
   728     {
       
   729     DEBUG( "core_server_c::create_eapol_instance()" );
       
   730 
       
   731     if ( eapol_m &&
       
   732         eapol_m->operating_mode() == mode )
       
   733         {
       
   734         DEBUG( "core_server_c::create_eapol_instance() - an instance already exists" );
       
   735 
       
   736         return true_t;
       
   737         }
       
   738 
       
   739     if ( eapol_m )
       
   740         {
       
   741         DEBUG( "core_server_c::create_eapol_instance() - deleting old core_wlan_eapol_interface_c instance" );
       
   742 
       
   743         eapol_m->shutdown();
       
   744         delete eapol_m;
       
   745         eapol_m = NULL;
       
   746         }
       
   747     
       
   748     DEBUG1( "core_server_c::create_eapol_instance() - creating core_wlan_eapol_interface_c (mode %u)",
       
   749         mode );
       
   750 
       
   751     eapol_m = new core_wlan_eapol_interface_c( callback_m );
       
   752     if ( !eapol_m )
       
   753         {
       
   754         DEBUG( "core_server_c::create_eapol_instance() - unable to create core_wlan_eapol_interface_c" );
       
   755         return false_t;
       
   756         }
       
   757     core_error_e error = eapol_m->load_eapol( mode, eapol_handler_m );
       
   758     if ( error != core_error_ok )
       
   759         {
       
   760         DEBUG1( "core_server_c::create_eapol_instance() - load_eapol failed with %i", error );
       
   761         delete eapol_m;
       
   762         eapol_m = NULL;
       
   763         return false_t;
       
   764         }
       
   765     error = eapol_m->configure();
       
   766     if ( error != core_error_ok )
       
   767         {
       
   768         DEBUG1( "core_server_c::create_eapol_instance() - configure failed with %i", error );
       
   769         delete eapol_m;
       
   770         eapol_m = NULL;
       
   771         return false_t;
       
   772         }
       
   773 
       
   774     return true_t;
       
   775     }
       
   776 
       
   777 // ---------------------------------------------------------------------------
       
   778 // ---------------------------------------------------------------------------
       
   779 //
       
   780 abs_core_frame_handler_c* core_server_c::frame_handler()
       
   781     {
       
   782     return frame_handler_m;
       
   783     }
       
   784 
       
   785 // ---------------------------------------------------------------------------
       
   786 // ---------------------------------------------------------------------------
       
   787 //
       
   788 void core_server_c::register_frame_handler(
       
   789     abs_core_frame_handler_c* handler )
       
   790     {
       
   791     ASSERT( handler );
       
   792     ASSERT( handler == frame_handler_m || !frame_handler_m );
       
   793 
       
   794     frame_handler_m = handler;
       
   795     }
       
   796 
       
   797 // ---------------------------------------------------------------------------
       
   798 // ---------------------------------------------------------------------------
       
   799 //
       
   800 void core_server_c::unregister_frame_handler(
       
   801     abs_core_frame_handler_c* handler )
       
   802     {
       
   803     ASSERT( handler );
       
   804     
       
   805     if ( frame_handler_m != handler )
       
   806         {
       
   807         DEBUG1( "core_server_c::unregister_frame_handler() - handler 0x%08X not registered",
       
   808             handler );
       
   809 
       
   810         return;
       
   811         }
       
   812 
       
   813     frame_handler_m = NULL;
       
   814     }
       
   815 
       
   816 // ---------------------------------------------------------------------------
       
   817 // ---------------------------------------------------------------------------
       
   818 //
       
   819 core_scan_list_c& core_server_c::get_scan_list()
       
   820     {
       
   821     return scan_list_m;
       
   822     }
       
   823 
       
   824 // ---------------------------------------------------------------------------
       
   825 // ---------------------------------------------------------------------------
       
   826 //
       
   827 abs_core_event_handler_c* core_server_c::event_handler()
       
   828     {
       
   829     return event_handler_m;
       
   830     }
       
   831 
       
   832 // ---------------------------------------------------------------------------
       
   833 // ---------------------------------------------------------------------------
       
   834 //
       
   835 void core_server_c::register_event_handler(
       
   836     abs_core_event_handler_c* handler )
       
   837     {
       
   838     ASSERT( handler );
       
   839     ASSERT( handler == event_handler_m || !event_handler_m );
       
   840 
       
   841     event_handler_m = handler;
       
   842     }
       
   843 
       
   844 // ---------------------------------------------------------------------------
       
   845 // ---------------------------------------------------------------------------
       
   846 //
       
   847 void core_server_c::unregister_event_handler(
       
   848     abs_core_event_handler_c* handler )
       
   849     {
       
   850     ASSERT( handler );
       
   851 
       
   852     if ( event_handler_m != handler )
       
   853         {
       
   854         DEBUG1( "core_server_c::unregister_event_handler() - handler 0x%08X not registered",
       
   855             handler );
       
   856 
       
   857         return;
       
   858         }
       
   859 
       
   860     event_handler_m = NULL;
       
   861     }
       
   862 
       
   863 // ---------------------------------------------------------------------------
       
   864 // ---------------------------------------------------------------------------
       
   865 //
       
   866 void core_server_c::schedule_roam(
       
   867     core_operation_handle_bss_lost_c::core_bss_lost_reason_e reason )
       
   868     {
       
   869     if ( !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) )
       
   870         {       
       
   871         DEBUG( "core_server_c::schedule_roam() - scheduling a core_operation_handle_bss_lost operation" );
       
   872 
       
   873         core_operation_base_c* command = new core_operation_handle_bss_lost_c(
       
   874             REQUEST_ID_CORE_INTERNAL,
       
   875             this,
       
   876             &drivers_m,
       
   877             &callback_m,
       
   878             reason );
       
   879 
       
   880         queue_int_operation_and_run_next( command );
       
   881         }
       
   882     else
       
   883         {
       
   884         DEBUG( "core_server_c::schedule_roam() - core_operation_handle_bss_lost already in the queue" );
       
   885         }        
       
   886     }
       
   887 
       
   888 // ---------------------------------------------------------------------------
       
   889 // ---------------------------------------------------------------------------
       
   890 //
       
   891 bool_t core_server_c::send_management_frame(
       
   892     core_frame_type_e frame_type,
       
   893     const u16_t frame_length,
       
   894     const u8_t* const frame_data,
       
   895     const core_mac_address_s& destination )
       
   896     {
       
   897     /** Management frames can be sent without downgraded user priority. */
       
   898     drivers_m.send_frame(
       
   899         frame_type,
       
   900         frame_length,
       
   901         frame_data,
       
   902         core_tools_c::convert_ac_to_user_priority( core_access_class_voice ),
       
   903         destination,
       
   904         true_t );    
       
   905 
       
   906     return true_t;
       
   907     }
       
   908 
       
   909 // ---------------------------------------------------------------------------
       
   910 // ---------------------------------------------------------------------------
       
   911 //
       
   912 bool_t core_server_c::send_data_frame(
       
   913     const core_ap_data_c& ap_data,
       
   914     core_frame_type_e frame_type,
       
   915     const u16_t frame_length,
       
   916     const u8_t* const frame_data,
       
   917     core_access_class_e frame_priority,
       
   918     const core_mac_address_s& destination,
       
   919     bool_t send_unencrypted )
       
   920     {
       
   921     DEBUG( "core_server_c::send_data_frame()" );
       
   922     
       
   923     u8_t initial_priority(
       
   924         core_tools_c::convert_ac_to_user_priority( frame_priority ) );
       
   925     u8_t user_priority = initial_priority;
       
   926       
       
   927     if ( ap_data.is_wmm_ie_present() )
       
   928         {
       
   929         /**
       
   930          * Collect a list of active streams per user priority.
       
   931          */
       
   932         bool_t is_ts_for_user_priority[MAX_QOS_USER_PRIORITY];
       
   933         core_tools_c::fillz(
       
   934             &is_ts_for_user_priority[0],
       
   935             sizeof( is_ts_for_user_priority ) );
       
   936 
       
   937         core_traffic_stream_list_iter_c iter(
       
   938             get_connection_data()->traffic_stream_list() );
       
   939 
       
   940         core_traffic_stream_c* entry = iter.first();
       
   941         while( entry )
       
   942             {
       
   943             if ( entry->status() == core_traffic_stream_status_active )
       
   944                 {
       
   945                 is_ts_for_user_priority[entry->user_priority()] = true_t;
       
   946                 }
       
   947 
       
   948             entry = iter.next();
       
   949             }
       
   950 
       
   951         /**
       
   952          * See if downgrade should be done.
       
   953          */
       
   954         bool_t is_send_ok( false_t );        
       
   955 
       
   956         while ( user_priority <= initial_priority && !is_send_ok )
       
   957             {
       
   958             core_access_class_e ac(
       
   959                 core_tools_c::convert_user_priority_to_ac( user_priority ) );
       
   960 
       
   961 #if 0
       
   962             DEBUG1( "core_server_c::send_data_frame() - user_priority is %u",
       
   963                 user_priority );
       
   964             DEBUG1( "core_server_c::send_data_frame() - ac is %u",
       
   965                 ac );
       
   966             DEBUG1( "core_server_c::send_data_frame() - is_admission_control_required is %u",
       
   967                 ap_data.is_admission_control_required( ac ) );
       
   968             DEBUG1( "core_server_c::send_data_frame() - is_ts_for_user_priority is %u",
       
   969                 is_ts_for_user_priority[user_priority] );
       
   970 #endif // 0
       
   971 
       
   972             if ( !ap_data.is_admission_control_required( ac ) ||
       
   973                  is_ts_for_user_priority[user_priority] )
       
   974                 {
       
   975                 is_send_ok = true_t;
       
   976                 }
       
   977             else
       
   978                 {
       
   979                 user_priority--;
       
   980                 }
       
   981             }
       
   982 
       
   983         if ( !is_send_ok )
       
   984             {
       
   985             DEBUG( "core_server_c::send_data_frame() - unable to send the frame due to admission control settings" );
       
   986             return false_t;
       
   987             }
       
   988         }
       
   989 
       
   990     if ( user_priority == initial_priority )
       
   991         {
       
   992         DEBUG1( "core_server_c::send_data_frame() - no need to downgrade user priority %u",
       
   993             user_priority );
       
   994         }
       
   995     else
       
   996         {
       
   997         DEBUG2( "core_server_c::send_data_frame() - user priority %u downgraded to %u",
       
   998             initial_priority, user_priority );
       
   999         }
       
  1000 
       
  1001     drivers_m.send_frame(
       
  1002         frame_type,
       
  1003         frame_length,
       
  1004         frame_data,
       
  1005         user_priority,
       
  1006         destination,
       
  1007         send_unencrypted ); 
       
  1008 
       
  1009     return true_t;
       
  1010     }
       
  1011 
       
  1012 // ---------------------------------------------------------------------------
       
  1013 // ---------------------------------------------------------------------------
       
  1014 //
       
  1015 abs_core_wpx_adaptation_c& core_server_c::get_wpx_adaptation_instance()
       
  1016     {
       
  1017     return *wpx_adaptation_m;
       
  1018     }
       
  1019 
       
  1020 // ---------------------------------------------------------------------------
       
  1021 // ---------------------------------------------------------------------------
       
  1022 //
       
  1023 void core_server_c::set_protected_setup_handler(
       
  1024     abs_core_protected_setup_handler_c* handler )
       
  1025     {
       
  1026     eapol_handler_m->set_protected_setup_handler( handler );
       
  1027     }
       
  1028 
       
  1029 // ---------------------------------------------------------------------------
       
  1030 // ---------------------------------------------------------------------------
       
  1031 //
       
  1032 void core_server_c::connect(
       
  1033     u32_t request_id,
       
  1034     const core_iap_data_s& settings,
       
  1035     core_connect_status_e& connect_status,
       
  1036     core_type_list_c<core_ssid_entry_s>* ssid_list )
       
  1037     {
       
  1038     DEBUG( "core_server_c::connect()" );
       
  1039 
       
  1040     core_operation_base_c* command = new core_operation_connect_c(
       
  1041         request_id, this, &drivers_m, &callback_m, settings, ssid_list, connect_status );
       
  1042 
       
  1043     queue_ext_operation_and_run_next( command, request_id );
       
  1044     }
       
  1045 
       
  1046 // ---------------------------------------------------------------------------
       
  1047 // ---------------------------------------------------------------------------
       
  1048 //
       
  1049 void core_server_c::release(
       
  1050     u32_t request_id )
       
  1051     {
       
  1052     DEBUG( "core_server_c::release()" );
       
  1053 
       
  1054     /**
       
  1055      * Cancel all pending roaming operations.
       
  1056      */
       
  1057     cancel_operations_with_flags(
       
  1058         core_operation_base_c::core_base_flag_roam_operation );
       
  1059 
       
  1060     /**
       
  1061      * If there's an executing roam operation, let it handle
       
  1062      * its own cancel.
       
  1063      */
       
  1064     core_operation_base_c* operation = queue_m.first();
       
  1065     if( operation &&
       
  1066         operation->is_flags( core_operation_base_c::core_base_flag_roam_operation ) )
       
  1067         {
       
  1068         operation->user_cancel_operation( true_t ); // Using graceful cancel
       
  1069         }
       
  1070 
       
  1071     core_operation_base_c* command = new core_operation_release_c(
       
  1072         request_id, this, &drivers_m, &callback_m, core_release_reason_external_request );
       
  1073 
       
  1074     queue_ext_operation_and_run_next( command, request_id );
       
  1075     }
       
  1076     
       
  1077 // ---------------------------------------------------------------------------
       
  1078 // ---------------------------------------------------------------------------
       
  1079 //
       
  1080 void core_server_c::get_scan_result(
       
  1081     u32_t request_id,
       
  1082     core_scan_mode_e scan_mode,
       
  1083     const core_ssid_s& scan_ssid,    
       
  1084     const core_scan_channels_s& scan_channels,
       
  1085     u8_t scan_max_age,
       
  1086     ScanList& scan_data,
       
  1087     bool_t is_current_ap_added )
       
  1088     {
       
  1089     DEBUG( "core_server_c::get_scan_result()" );
       
  1090     
       
  1091     core_operation_base_c* command = new core_operation_scan_c(
       
  1092         request_id, this, &drivers_m, &callback_m,
       
  1093         scan_mode, scan_ssid, scan_channels, scan_max_age, scan_data, 
       
  1094         true_t,
       
  1095         is_current_ap_added );
       
  1096 
       
  1097     queue_ext_operation_and_run_next( command, request_id );    
       
  1098     }
       
  1099     
       
  1100 // ---------------------------------------------------------------------------
       
  1101 // ---------------------------------------------------------------------------
       
  1102 //
       
  1103 void core_server_c::get_available_iaps(
       
  1104     u32_t request_id,
       
  1105     bool_t is_active_scan_allowed,
       
  1106     core_type_list_c<core_iap_data_s>& iap_data_list,
       
  1107     core_type_list_c<u32_t>& iap_id_list,
       
  1108     core_type_list_c<core_ssid_entry_s>* iap_ssid_list,
       
  1109     ScanList& scan_data )
       
  1110     {
       
  1111     DEBUG( "core_server_c::get_available_iaps()" );
       
  1112 
       
  1113     core_operation_base_c* command = new core_operation_get_available_iaps_c(
       
  1114         request_id, 
       
  1115         this, 
       
  1116         &drivers_m, 
       
  1117         &callback_m, 
       
  1118         is_active_scan_allowed, 
       
  1119         iap_data_list, 
       
  1120         iap_id_list,
       
  1121         iap_ssid_list,
       
  1122         scan_data );
       
  1123 
       
  1124     queue_ext_operation_and_run_next( command, request_id );
       
  1125     }
       
  1126 
       
  1127 // ---------------------------------------------------------------------------
       
  1128 // ---------------------------------------------------------------------------
       
  1129 //
       
  1130 void core_server_c::get_current_rcpi(
       
  1131     u32_t request_id,
       
  1132     u32_t& rcpi )
       
  1133     {
       
  1134     DEBUG( "core_server_c::get_current_rcpi()" );
       
  1135     
       
  1136     core_operation_base_c* command = new core_operation_get_rcpi_c(
       
  1137         request_id, this, &drivers_m, &callback_m, rcpi );
       
  1138 
       
  1139     queue_ext_operation_and_run_next( command, request_id );    
       
  1140     }
       
  1141 
       
  1142 // ---------------------------------------------------------------------------
       
  1143 // ---------------------------------------------------------------------------
       
  1144 //
       
  1145 void core_server_c::disable_wlan(
       
  1146     u32_t request_id )
       
  1147     {
       
  1148     DEBUG( "core_server_c::disable_wlan()" );
       
  1149 
       
  1150     get_core_settings().set_wlan_enabled( false_t );
       
  1151 
       
  1152     /**
       
  1153      * Schedule an immediate driver unload.
       
  1154      */ 
       
  1155     unload_drivers();
       
  1156 
       
  1157     core_operation_base_c* command = new core_operation_null_c(
       
  1158         request_id, this, &drivers_m, &callback_m, core_error_ok );
       
  1159 
       
  1160     queue_ext_operation_and_run_next( command, request_id );
       
  1161     }
       
  1162 
       
  1163 // ---------------------------------------------------------------------------
       
  1164 // ---------------------------------------------------------------------------
       
  1165 //
       
  1166 void core_server_c::enable_wlan(
       
  1167     u32_t request_id )
       
  1168     {
       
  1169     DEBUG( "core_server_c::enable_wlan()" );
       
  1170     
       
  1171     core_settings_m.set_wlan_enabled( true_t );
       
  1172     
       
  1173     core_operation_base_c* command = new core_operation_null_c(
       
  1174         request_id, this, &drivers_m, &callback_m, core_error_ok );
       
  1175 
       
  1176     queue_ext_operation_and_run_next( command, request_id );
       
  1177     }
       
  1178 
       
  1179 // ---------------------------------------------------------------------------
       
  1180 // ---------------------------------------------------------------------------
       
  1181 //
       
  1182 core_error_e core_server_c::unload_drivers()
       
  1183     {
       
  1184     DEBUG( "core_server_c::unload_drivers()" );
       
  1185 
       
  1186     /**
       
  1187      * If drivers are loaded, schedule an immediate unload.
       
  1188      */
       
  1189     if( get_core_settings().is_driver_loaded() )
       
  1190         {
       
  1191         cancel_unload_timer();
       
  1192         schedule_unload_timer( CORE_TIMER_IMMEDIATELY );
       
  1193 
       
  1194         return core_error_ok;
       
  1195         }
       
  1196     else
       
  1197         {
       
  1198         return core_error_drivers_not_loaded;
       
  1199         }
       
  1200     }
       
  1201 
       
  1202 // ---------------------------------------------------------------------------
       
  1203 // ---------------------------------------------------------------------------
       
  1204 //
       
  1205 void core_server_c::get_packet_statistics(
       
  1206     u32_t request_id,
       
  1207     core_packet_statistics_s& statistics )
       
  1208     {
       
  1209     DEBUG( "core_server_c::get_packet_statistics()" );
       
  1210 
       
  1211     core_operation_base_c* command = new core_operation_get_statistics_c(
       
  1212         request_id, this, &drivers_m, &callback_m, statistics );
       
  1213 
       
  1214     queue_ext_operation_and_run_next( command, request_id );
       
  1215     }
       
  1216 
       
  1217 // ---------------------------------------------------------------------------
       
  1218 // ---------------------------------------------------------------------------
       
  1219 //
       
  1220 void core_server_c::create_traffic_stream(
       
  1221     u32_t request_id,
       
  1222     u8_t tid,
       
  1223     u8_t user_priority,
       
  1224     bool_t is_automatic_stream,
       
  1225     const core_traffic_stream_params_s& params,
       
  1226     u32_t& stream_id,
       
  1227     core_traffic_stream_status_e& stream_status )
       
  1228     {
       
  1229     DEBUG( "core_server_c::create_traffic_stream()" );
       
  1230 
       
  1231     core_operation_base_c* command = new core_operation_create_ts_c(
       
  1232         request_id,
       
  1233         this,
       
  1234         &drivers_m,
       
  1235         &callback_m,
       
  1236         tid,
       
  1237         user_priority,
       
  1238         is_automatic_stream,
       
  1239         params,
       
  1240         stream_id,
       
  1241         stream_status );
       
  1242    
       
  1243     queue_ext_operation_and_run_next( command, request_id );    
       
  1244     }
       
  1245 
       
  1246 // ---------------------------------------------------------------------------
       
  1247 // ---------------------------------------------------------------------------
       
  1248 //
       
  1249 void core_server_c::delete_traffic_stream(
       
  1250     u32_t request_id,
       
  1251     u32_t stream_id )
       
  1252     {
       
  1253     DEBUG( "core_server_c::delete_traffic_stream()" );
       
  1254 
       
  1255     core_operation_base_c* command = new core_operation_delete_ts_c(
       
  1256         request_id,
       
  1257         this,
       
  1258         &drivers_m,
       
  1259         &callback_m,
       
  1260         stream_id );
       
  1261 
       
  1262     queue_ext_operation_and_run_next( command, request_id );    
       
  1263     }
       
  1264 
       
  1265 // ---------------------------------------------------------------------------
       
  1266 // ---------------------------------------------------------------------------
       
  1267 // 
       
  1268 void core_server_c::run_protected_setup(
       
  1269     u32_t request_id, 
       
  1270     const core_iap_data_s& iap_data,
       
  1271     core_type_list_c<core_iap_data_s>& iap_data_list,
       
  1272     core_protected_setup_status_e& protected_setup_status )
       
  1273     {
       
  1274     DEBUG( "core_server_c::run_protected_setup()" );
       
  1275     
       
  1276     core_operation_base_c* command = new core_operation_protected_setup_c(
       
  1277         request_id, this, &drivers_m, &callback_m, iap_data, iap_data_list,
       
  1278         protected_setup_status );
       
  1279 
       
  1280     queue_ext_operation_and_run_next( command, request_id );
       
  1281     }
       
  1282 
       
  1283 // ---------------------------------------------------------------------------
       
  1284 // ---------------------------------------------------------------------------
       
  1285 //
       
  1286 void core_server_c::directed_roam(
       
  1287     u32_t request_id,
       
  1288     const core_mac_address_s& bssid )
       
  1289     {
       
  1290     DEBUG( "core_server_c::directed_roam()" );
       
  1291 
       
  1292     core_operation_base_c* command = new core_operation_directed_roam_c(
       
  1293         request_id, this, &drivers_m, &callback_m, bssid );
       
  1294 
       
  1295     queue_ext_operation_and_run_next( command, request_id );
       
  1296     }
       
  1297 
       
  1298 // ---------------------------------------------------------------------------
       
  1299 // ---------------------------------------------------------------------------
       
  1300 //
       
  1301 core_error_e core_server_c::get_current_bssid(
       
  1302     core_mac_address_s& bssid )
       
  1303     {
       
  1304     DEBUG( "core_server_c::get_current_bssid()" );
       
  1305 
       
  1306     bssid = ZERO_MAC_ADDR;
       
  1307     if ( core_settings_m.is_connected() &&
       
  1308          connection_data_m &&
       
  1309          connection_data_m->current_ap_data() )
       
  1310         {
       
  1311         bssid = connection_data_m->current_ap_data()->bssid();
       
  1312 
       
  1313         return core_error_ok;
       
  1314         }
       
  1315 
       
  1316     return core_error_not_connected;
       
  1317     }
       
  1318 
       
  1319 // ---------------------------------------------------------------------------
       
  1320 // ---------------------------------------------------------------------------
       
  1321 //
       
  1322 core_error_e core_server_c::get_current_ssid(
       
  1323     core_ssid_s& ssid )
       
  1324     {
       
  1325     DEBUG( "core_server_c::get_current_ssid()" );
       
  1326 
       
  1327     ssid = BROADCAST_SSID;
       
  1328     if ( core_settings_m.is_connected() &&
       
  1329          connection_data_m &&
       
  1330          connection_data_m->current_ap_data() )
       
  1331         {
       
  1332         ssid = connection_data_m->ssid();
       
  1333 
       
  1334         return core_error_ok;
       
  1335         }
       
  1336 
       
  1337     return core_error_not_connected;
       
  1338     }
       
  1339 
       
  1340 // ---------------------------------------------------------------------------
       
  1341 // ---------------------------------------------------------------------------
       
  1342 //
       
  1343 core_error_e core_server_c::get_current_security_mode(
       
  1344     core_connection_security_mode_e& mode )
       
  1345     {
       
  1346     DEBUG( "core_server_c::get_current_security_mode()" );
       
  1347 
       
  1348     mode = core_connection_security_mode_open;
       
  1349     if ( core_settings_m.is_connected() &&
       
  1350          connection_data_m &&
       
  1351          connection_data_m->current_ap_data() )
       
  1352         {
       
  1353         mode = core_tools_c::security_mode(
       
  1354             connection_data_m->iap_data(),
       
  1355             *connection_data_m->current_ap_data() );
       
  1356 
       
  1357         return core_error_ok;
       
  1358         }
       
  1359 
       
  1360     return core_error_not_connected;
       
  1361     }
       
  1362     
       
  1363 // ---------------------------------------------------------------------------
       
  1364 // ---------------------------------------------------------------------------
       
  1365 //
       
  1366 core_error_e core_server_c::get_current_connection_state(
       
  1367     core_connection_state_e& state )
       
  1368     {
       
  1369     DEBUG( "core_server_c::get_current_connection_state()" );
       
  1370 
       
  1371     state = core_settings_m.connection_state();
       
  1372 
       
  1373     return core_error_ok;
       
  1374     }
       
  1375     
       
  1376 // ---------------------------------------------------------------------------
       
  1377 // ---------------------------------------------------------------------------
       
  1378 //
       
  1379 core_error_e core_server_c::update_device_settings(
       
  1380     core_device_settings_s& settings )
       
  1381     {
       
  1382     DEBUG( "core_server_c::update_device_settings()" );
       
  1383 
       
  1384     device_settings_m = settings;
       
  1385 
       
  1386     core_operation_base_c* command = new core_operation_update_device_settings_c(
       
  1387         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m );
       
  1388 
       
  1389     queue_int_operation_and_run_next( command );
       
  1390 
       
  1391     return core_error_ok;
       
  1392     }
       
  1393     
       
  1394 // ---------------------------------------------------------------------------
       
  1395 // ---------------------------------------------------------------------------
       
  1396 //
       
  1397 core_error_e core_server_c::set_power_save_mode(
       
  1398     const core_power_save_mode_s& mode )
       
  1399     {
       
  1400     DEBUG( "core_server_c::set_power_save_mode()" );
       
  1401 
       
  1402     core_settings_m.set_preferred_power_save_mode( mode );
       
  1403 
       
  1404     core_operation_base_c* command = new core_operation_update_power_mode_c(
       
  1405         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m );
       
  1406 
       
  1407     queue_int_operation_and_run_next( command );
       
  1408 
       
  1409     return core_error_ok;        
       
  1410     }
       
  1411     
       
  1412 // ---------------------------------------------------------------------------
       
  1413 // ---------------------------------------------------------------------------
       
  1414 //
       
  1415 core_error_e core_server_c::add_bssid_to_rogue_list(
       
  1416     const core_mac_address_s& bssid )
       
  1417     {
       
  1418     DEBUG( "core_server_c::add_bssid_to_rogue_list()" );
       
  1419 
       
  1420     core_settings_m.add_mac_to_permanent_blacklist(
       
  1421         bssid, core_ap_blacklist_reason_external );
       
  1422 
       
  1423     return core_error_ok;
       
  1424     }
       
  1425 
       
  1426 // ---------------------------------------------------------------------------
       
  1427 // ---------------------------------------------------------------------------
       
  1428 //   
       
  1429 core_error_e core_server_c::remove_bssid_from_rogue_list(
       
  1430     const core_mac_address_s& bssid )
       
  1431     {
       
  1432     DEBUG( "core_server_c::remove_bssid_from_rogue_list()" );
       
  1433 
       
  1434     core_settings_m.remove_mac_from_permanent_blacklist( bssid );
       
  1435 
       
  1436     return core_error_ok;
       
  1437     }
       
  1438 
       
  1439 // ---------------------------------------------------------------------------
       
  1440 // ---------------------------------------------------------------------------
       
  1441 //
       
  1442 core_error_e core_server_c::get_rogue_list(
       
  1443     core_type_list_c<core_mac_address_s>& rogue_list )
       
  1444     {
       
  1445     DEBUG( "core_server_c::get_rogue_list()" );
       
  1446 
       
  1447     core_type_list_c<core_ap_blacklist_entry_s>& perm_list = core_settings_m.permanent_blacklist();
       
  1448     DEBUG1( "core_server_c::get_rogue_list() - %d permanent addresses", perm_list.count() );
       
  1449 
       
  1450     // Loop through permanent blacklist
       
  1451     core_ap_blacklist_entry_s* addr = perm_list.first();
       
  1452     while ( addr )
       
  1453         {
       
  1454         // Address must be copied, because rogue_list get ownership for its entries.
       
  1455         core_mac_address_s* copy_addr = new core_mac_address_s;
       
  1456         if ( !copy_addr )
       
  1457             {
       
  1458             return core_error_no_memory;
       
  1459             }
       
  1460         *copy_addr = addr->bssid;
       
  1461         DEBUG_MAC( copy_addr->addr );
       
  1462         
       
  1463         core_error_e status = rogue_list.append( copy_addr );
       
  1464         if ( status != core_error_ok )
       
  1465             {
       
  1466             return status;
       
  1467             }
       
  1468 
       
  1469         addr = perm_list.next();
       
  1470         }
       
  1471 
       
  1472     // Check if connection is available.
       
  1473     if ( connection_data_m )
       
  1474         {
       
  1475         core_type_list_c<core_ap_blacklist_entry_s>& temp_list = connection_data_m->temporary_blacklist();
       
  1476         DEBUG1( "core_server_c::get_rogue_list() - %d temporary addresses", temp_list.count() );
       
  1477         
       
  1478         // Loop through temporary blacklist
       
  1479         addr = temp_list.first();
       
  1480         while ( addr )
       
  1481             {
       
  1482             // Address must be copied, because rogue_list get ownership for its entries.
       
  1483             core_mac_address_s* copy_addr = new core_mac_address_s;
       
  1484             if ( !copy_addr )
       
  1485                 {
       
  1486                 return core_error_no_memory;
       
  1487                 }
       
  1488             *copy_addr = addr->bssid;
       
  1489             DEBUG_MAC( copy_addr->addr );
       
  1490             
       
  1491             core_error_e status = rogue_list.append( copy_addr );
       
  1492             if ( status != core_error_ok )
       
  1493                 {
       
  1494                 return status;
       
  1495                 }
       
  1496     
       
  1497             addr = temp_list.next();
       
  1498             }
       
  1499         }
       
  1500     else
       
  1501         {
       
  1502         DEBUG( "core_server_c::get_rogue_list() - connection is not available, temporary blacklist is empty" );
       
  1503         }
       
  1504 
       
  1505     return core_error_ok;
       
  1506     }
       
  1507 
       
  1508 // ---------------------------------------------------------------------------
       
  1509 // ---------------------------------------------------------------------------
       
  1510 //  
       
  1511 core_error_e core_server_c::set_rcp_level_notification_boundary(
       
  1512     const i32_t rcp_level_boundary,
       
  1513     const i32_t hysteresis )
       
  1514     {
       
  1515     DEBUG( "core_server_c::set_rcp_level_notification_boundary()" );
       
  1516 
       
  1517     core_settings_m.set_rcpi_boundaries(
       
  1518         rcp_level_boundary,
       
  1519         rcp_level_boundary + hysteresis );
       
  1520 
       
  1521     return core_error_ok;
       
  1522     }
       
  1523 
       
  1524 // ---------------------------------------------------------------------------
       
  1525 // ---------------------------------------------------------------------------
       
  1526 //
       
  1527 core_error_e core_server_c::clear_packet_statistics()
       
  1528     {
       
  1529     DEBUG( "core_server_c::clear_packet_statistics()" );
       
  1530 
       
  1531     core_settings_m.clear_connection_statistics();
       
  1532     core_settings_m.roam_metrics().clear_metrics();
       
  1533 
       
  1534     return core_error_ok;
       
  1535     }
       
  1536 
       
  1537 // ---------------------------------------------------------------------------
       
  1538 // ---------------------------------------------------------------------------
       
  1539 //    
       
  1540 core_error_e core_server_c::get_uapsd_settings(
       
  1541     core_uapsd_settings_s& settings )
       
  1542     {
       
  1543     DEBUG( "core_server_c::get_uapsd_settings()" );
       
  1544 
       
  1545     settings = core_settings_m.uapsd_settings();
       
  1546 
       
  1547     return core_error_ok;
       
  1548     }
       
  1549 
       
  1550 // ---------------------------------------------------------------------------
       
  1551 // ---------------------------------------------------------------------------
       
  1552 //   
       
  1553 core_error_e core_server_c::set_uapsd_settings(
       
  1554     const core_uapsd_settings_s& settings )
       
  1555     {
       
  1556     DEBUG( "core_server_c::set_uapsd_settings()" );
       
  1557 
       
  1558     core_operation_base_c* command = new core_operation_set_uapsd_settings_c(
       
  1559         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, settings );
       
  1560 
       
  1561     queue_int_operation_and_run_next( command );
       
  1562 
       
  1563     return core_error_ok;  
       
  1564     }
       
  1565 
       
  1566 // ---------------------------------------------------------------------------
       
  1567 // ---------------------------------------------------------------------------
       
  1568 //    
       
  1569 core_error_e core_server_c::get_power_save_settings(
       
  1570     core_power_save_settings_s& settings )
       
  1571     {
       
  1572     DEBUG( "core_server_c::get_power_save_settings()" );
       
  1573 
       
  1574     settings = core_settings_m.power_save_settings();
       
  1575 
       
  1576     return core_error_ok;
       
  1577     }
       
  1578 
       
  1579 // ---------------------------------------------------------------------------
       
  1580 // ---------------------------------------------------------------------------
       
  1581 //   
       
  1582 core_error_e core_server_c::set_power_save_settings(
       
  1583     const core_power_save_settings_s& settings )
       
  1584     {
       
  1585     DEBUG( "core_server_c::set_power_save_settings()" );
       
  1586 
       
  1587     core_operation_base_c* command = new core_operation_set_power_save_settings_c(
       
  1588         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, settings );
       
  1589 
       
  1590     queue_int_operation_and_run_next( command );
       
  1591 
       
  1592     return core_error_ok;  
       
  1593     }
       
  1594 
       
  1595 // ---------------------------------------------------------------------------
       
  1596 // ---------------------------------------------------------------------------
       
  1597 //
       
  1598 core_error_e core_server_c::get_current_ap_info(
       
  1599     core_ap_information_s& info )
       
  1600     {
       
  1601     DEBUG( "core_server_c::get_current_ap_info()" );
       
  1602 
       
  1603     if ( core_settings_m.is_connected() &&
       
  1604          connection_data_m &&
       
  1605          connection_data_m->current_ap_data() )
       
  1606         {
       
  1607         info = core_tools_parser_c::get_ap_info(
       
  1608             connection_data_m->iap_data(),
       
  1609             *connection_data_m->current_ap_data() );
       
  1610 
       
  1611         return core_error_ok;
       
  1612         }
       
  1613 
       
  1614     return core_error_not_connected;
       
  1615     }
       
  1616 
       
  1617 // ---------------------------------------------------------------------------
       
  1618 // ---------------------------------------------------------------------------
       
  1619 //
       
  1620 void core_server_c::get_roam_metrics(
       
  1621     core_roam_metrics_s& roam_metrics )
       
  1622     {
       
  1623     DEBUG( "core_server_c::get_roam_metrics()" );
       
  1624 
       
  1625     core_roam_metrics_c& metrics = get_core_settings().roam_metrics();
       
  1626 
       
  1627     roam_metrics.connection_attempt_total_count = metrics.roam_attempt_count( core_roam_reason_initial_connect );
       
  1628     roam_metrics.unsuccesfull_connection_attempt_count = 
       
  1629           metrics.roam_attempt_failed_count( core_roam_failed_reason_timeout )
       
  1630         + metrics.roam_attempt_failed_count( core_roam_failed_reason_ap_status_code )
       
  1631         + metrics.roam_attempt_failed_count( core_roam_failed_reason_eapol_failure )
       
  1632         + metrics.roam_attempt_failed_count( core_roam_failed_reason_other_failure );
       
  1633 
       
  1634     roam_metrics.roaming_counter = metrics.roam_success_count();
       
  1635     roam_metrics.coverage_loss_count = metrics.roam_attempt_count( core_roam_reason_bss_lost );
       
  1636 
       
  1637     roam_metrics.last_roam_total_duration = metrics.roam_total_delay() / MILLISECONDS_FROM_MICROSECONDS;
       
  1638     roam_metrics.last_roam_data_path_broken_duration = metrics.roam_total_delay() / MILLISECONDS_FROM_MICROSECONDS;
       
  1639 
       
  1640     roam_metrics.last_roam_reason = core_roam_reason_none;
       
  1641     if ( get_connection_data() )
       
  1642         {
       
  1643         roam_metrics.last_roam_reason = get_connection_data()->last_roam_reason();
       
  1644         }
       
  1645     }
       
  1646 
       
  1647 // ---------------------------------------------------------------------------
       
  1648 // ---------------------------------------------------------------------------
       
  1649 //
       
  1650 core_error_e core_server_c::set_arp_filter(
       
  1651     const core_arp_filter_s& filter )
       
  1652     {
       
  1653     DEBUG( "core_server_c::set_arp_filter()" );
       
  1654 
       
  1655     core_operation_base_c* command = new core_operation_set_arp_filter_c(
       
  1656         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, filter );
       
  1657 
       
  1658     queue_int_operation_and_run_next( command );
       
  1659 
       
  1660     return core_error_ok;
       
  1661     }
       
  1662 
       
  1663 // ---------------------------------------------------------------------------
       
  1664 // ---------------------------------------------------------------------------
       
  1665 //
       
  1666 core_error_e core_server_c::configure_multicast_group(
       
  1667     bool_t join_group,
       
  1668     const core_mac_address_s& multicast_addr )
       
  1669     {
       
  1670     DEBUG( "core_server_c::configure_multicast_group" );
       
  1671 
       
  1672     core_operation_base_c* command = new core_operation_configure_multicast_group_c(
       
  1673         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, join_group, multicast_addr );
       
  1674 
       
  1675     queue_int_operation_and_run_next( command );
       
  1676 
       
  1677     return core_error_ok;
       
  1678     }
       
  1679 
       
  1680 // ---------------------------------------------------------------------------
       
  1681 // ---------------------------------------------------------------------------
       
  1682 //
       
  1683 core_error_e core_server_c::get_current_ac_traffic_info(
       
  1684     core_ac_traffic_information_s& info )
       
  1685     {
       
  1686     DEBUG( "core_server_c::get_current_ac_traffic_info()" );
       
  1687 
       
  1688     if ( core_settings_m.is_connected() &&
       
  1689          connection_data_m &&
       
  1690          connection_data_m->current_ap_data() )
       
  1691         {
       
  1692         info.status_for_voice = connection_data_m->ac_traffic_status(
       
  1693             core_access_class_voice );
       
  1694         info.status_for_video = connection_data_m->ac_traffic_status(
       
  1695             core_access_class_video );
       
  1696         info.status_for_best_effort = connection_data_m->ac_traffic_status(
       
  1697             core_access_class_best_effort );
       
  1698         info.status_for_background = connection_data_m->ac_traffic_status(
       
  1699             core_access_class_background );
       
  1700         info.mode_for_voice = connection_data_m->ac_traffic_mode(
       
  1701             core_access_class_voice );
       
  1702         info.mode_for_video = connection_data_m->ac_traffic_mode(
       
  1703             core_access_class_video );
       
  1704         info.mode_for_best_effort = connection_data_m->ac_traffic_mode(
       
  1705             core_access_class_best_effort );
       
  1706         info.mode_for_background = connection_data_m->ac_traffic_mode(
       
  1707             core_access_class_background );
       
  1708 
       
  1709         return core_error_ok;
       
  1710         }
       
  1711 
       
  1712     return core_error_not_connected;    
       
  1713     }
       
  1714 
       
  1715 // ---------------------------------------------------------------------------
       
  1716 // ---------------------------------------------------------------------------
       
  1717 //
       
  1718 void core_server_c::request_complete(
       
  1719     u32_t /* request_id */,
       
  1720     core_error_e status )
       
  1721     {
       
  1722     DEBUG( "core_server_c::request_complete()" );
       
  1723     
       
  1724     core_operation_base_c* operation = queue_m.first();
       
  1725     
       
  1726     ASSERT( operation );
       
  1727     ASSERT( operation->is_executing() );
       
  1728 
       
  1729     core_error_e ret = operation->continue_operation( status );
       
  1730     if ( ret == core_error_request_pending )
       
  1731         {
       
  1732         DEBUG( "core_server_c::request_complete() - operation is not done yet" );
       
  1733         return;
       
  1734         }
       
  1735 
       
  1736     DEBUG1( "core_server_c::request_complete() - operation completed with code %u",
       
  1737         ret );
       
  1738 
       
  1739     if ( operation->request_id() != REQUEST_ID_CORE_INTERNAL )
       
  1740         {
       
  1741         callback_m.request_complete(
       
  1742             operation->request_id(),
       
  1743             ret );
       
  1744         }
       
  1745 
       
  1746     queue_m.remove( operation );
       
  1747     delete operation;
       
  1748     operation = NULL;
       
  1749 
       
  1750     schedule_operation();
       
  1751     }
       
  1752 
       
  1753 // ---------------------------------------------------------------------------
       
  1754 // ---------------------------------------------------------------------------
       
  1755 //
       
  1756 void core_server_c::cancel_request(
       
  1757     u32_t request_id )
       
  1758     {
       
  1759     DEBUG( "core_server_c::cancel_request()" );
       
  1760     
       
  1761     // Find correct operation
       
  1762     core_operation_base_c* operation = queue_m.first();
       
  1763     while ( operation )
       
  1764         {
       
  1765         if ( operation->request_id() == request_id )
       
  1766             {
       
  1767             break;
       
  1768             }
       
  1769         operation = queue_m.next();
       
  1770         }
       
  1771     
       
  1772     if ( !operation )
       
  1773         {
       
  1774         DEBUG( "core_server_c::cancel_request() - operation not found" );
       
  1775         return;
       
  1776         }
       
  1777     
       
  1778     if ( operation->is_executing() )
       
  1779         {
       
  1780         // Let operation handle it's own cancelling
       
  1781         operation->user_cancel_operation( true_t ); // Using graceful cancel
       
  1782         }
       
  1783     else
       
  1784         {
       
  1785         // When operation is not yet running, we don't need to ask for it's permissions...
       
  1786         queue_m.remove( operation );
       
  1787         delete operation;
       
  1788         operation = NULL;
       
  1789         
       
  1790         // Use null operation for completing correctly
       
  1791         operation = new core_operation_null_c(
       
  1792             request_id, this, &drivers_m, &callback_m, core_error_cancel );
       
  1793         queue_ext_operation_and_run_next( operation, request_id );
       
  1794         }
       
  1795     }
       
  1796 
       
  1797 // ---------------------------------------------------------------------------
       
  1798 // ---------------------------------------------------------------------------
       
  1799 //  
       
  1800 void core_server_c::receive_frame(
       
  1801     core_frame_type_e frame_type,
       
  1802     const u16_t frame_length,
       
  1803     const u8_t* const frame_data,
       
  1804     u8_t frame_rcpi )
       
  1805     {
       
  1806     DEBUG( "core_server_c::receive_frame()" );
       
  1807 
       
  1808     DEBUG1( "core_server_c::receive_frame() - frame type: %u", frame_type );
       
  1809     DEBUG1( "core_server_c::receive_frame() - frame (%u bytes): ",
       
  1810         frame_length );
       
  1811     DEBUG_BUFFER(
       
  1812         frame_length,
       
  1813         frame_data );
       
  1814 
       
  1815     if ( frame_type == core_frame_type_ethernet )
       
  1816         {
       
  1817         core_frame_ethernet_c* frame = core_frame_ethernet_c::instance(
       
  1818             frame_length,
       
  1819             frame_data,
       
  1820             false_t );
       
  1821         if ( frame )             
       
  1822             {
       
  1823             /**
       
  1824              * Currently all Ethernet frames are for EAPOL.
       
  1825              */
       
  1826 
       
  1827             /**
       
  1828              * If an Ethernet frame is received during a roam, store it
       
  1829              * for later use.
       
  1830              */
       
  1831             if ( get_connection_data()->is_eapol_connecting() )
       
  1832                 {
       
  1833                 DEBUG( "core_server_c::receive_frame() - (re-)association in progress, storing EAPOL frame" );
       
  1834 
       
  1835                 (void)eapol_m->store_frame( *frame );
       
  1836                 }
       
  1837             /**
       
  1838              * Frames are discarded during disconnect.
       
  1839              */
       
  1840             else if ( get_connection_data()->is_disconnecting() )
       
  1841                 {
       
  1842                 DEBUG( "core_server_c::receive_frame() - disconnect in progress, discarding EAPOL frame" );
       
  1843                 }
       
  1844             /**
       
  1845              * Otherwise send it to EAPOL for processing.
       
  1846              */
       
  1847             else if ( eapol_m )
       
  1848                 {
       
  1849                 // Clear stored frame so that it is not sent later.
       
  1850                 eapol_m->clear_stored_frame();
       
  1851                 
       
  1852                 (void)eapol_m->process_frame( *frame );
       
  1853                 }
       
  1854             else
       
  1855                 {
       
  1856                 DEBUG( "core_server_c::receive_frame() - EAPOL not instantiated, discarding EAPOL frame" );
       
  1857                 }
       
  1858 
       
  1859             delete frame;
       
  1860             frame = NULL;
       
  1861             }
       
  1862 
       
  1863         return;
       
  1864         }
       
  1865 
       
  1866     /**
       
  1867      * WPX frames are handled separately.
       
  1868      */
       
  1869     if ( wpx_adaptation_m->handle_wpx_frame(
       
  1870             frame_type,
       
  1871             frame_length,
       
  1872             frame_data ) )
       
  1873         {
       
  1874         return;
       
  1875         }
       
  1876 
       
  1877     /**
       
  1878      * Offer dot11 and echo test frames to the registered frame handler.
       
  1879      */
       
  1880     bool_t is_handled( false_t );
       
  1881 
       
  1882     if ( frame_type == core_frame_type_dot11 &&
       
  1883          frame_handler_m )
       
  1884         {                
       
  1885         core_frame_dot11_c* frame = core_frame_dot11_c::instance(
       
  1886             frame_length,
       
  1887             frame_data,
       
  1888             false_t );
       
  1889         if ( frame &&
       
  1890              frame_handler_m->receive_frame( frame, frame_rcpi ) )
       
  1891             {
       
  1892             DEBUG( "core_server_c::receive_frame() - dot11 frame handled by the operation" );
       
  1893 
       
  1894             is_handled = true_t;
       
  1895             }
       
  1896 
       
  1897         delete frame;
       
  1898         frame = NULL;
       
  1899         }
       
  1900     else if ( frame_type == core_frame_type_test &&
       
  1901               frame_handler_m )
       
  1902         {
       
  1903         core_frame_ethernet_c* frame = core_frame_ethernet_c::instance(
       
  1904             frame_length,
       
  1905             frame_data,
       
  1906             false_t );
       
  1907         if ( frame )
       
  1908             {
       
  1909             core_frame_echo_test_c* test_frame = core_frame_echo_test_c::instance(
       
  1910                 *frame );
       
  1911             if ( test_frame &&
       
  1912                  frame_handler_m->receive_test_frame( test_frame, frame_rcpi ) )
       
  1913                 {
       
  1914                 DEBUG( "core_server_c::receive_frame() - echo test frame handled by the operation" );
       
  1915 
       
  1916                 is_handled = true_t;                
       
  1917                 }
       
  1918 
       
  1919             delete test_frame;
       
  1920             test_frame = NULL;
       
  1921 
       
  1922             delete frame;
       
  1923             frame = NULL;            
       
  1924             }
       
  1925         }
       
  1926 
       
  1927     /**
       
  1928      * All other frames are processed in an operation.
       
  1929      */
       
  1930     if ( !is_handled )
       
  1931         {
       
  1932         DEBUG( "core_server_c::receive_frame() - queueing the frame for processing" );
       
  1933 
       
  1934         core_operation_base_c* command = new core_operation_handle_frame_c(
       
  1935             REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m,
       
  1936             frame_type, frame_length, frame_data );
       
  1937 
       
  1938         queue_int_operation_and_run_next( command );
       
  1939         }
       
  1940     }
       
  1941 
       
  1942 // ---------------------------------------------------------------------------
       
  1943 // ---------------------------------------------------------------------------
       
  1944 //    
       
  1945 void core_server_c::notify(
       
  1946     core_am_indication_e indication )
       
  1947     {
       
  1948     DEBUG( "core_server_c::notify()" );
       
  1949 
       
  1950 #ifdef _DEBUG
       
  1951     switch ( indication )
       
  1952         {
       
  1953         case core_am_indication_wlan_media_disconnect:
       
  1954             DEBUG( "core_server_c::notify() - core_am_indication_wlan_media_disconnect" );
       
  1955             break;
       
  1956         case core_am_indication_wlan_hw_failed:
       
  1957             DEBUG( "core_server_c::notify() - core_am_indication_wlan_hw_failed" );
       
  1958             break;
       
  1959         case core_am_indication_wlan_beacon_lost:
       
  1960             DEBUG( "core_server_c::notify() - core_am_indication_wlan_beacon_lost" );
       
  1961             break;
       
  1962         case core_am_indication_wlan_power_mode_failure:
       
  1963             DEBUG( "core_server_c::notify() - core_am_indication_wlan_power_mode_failure" );
       
  1964             break;
       
  1965         case core_am_indication_wlan_tx_fail:
       
  1966             DEBUG( "core_server_c::notify() - core_am_indication_wlan_tx_fail" );
       
  1967             break;
       
  1968         case core_am_indication_wlan_bss_regained:
       
  1969             DEBUG( "core_server_c::notify() - core_am_indication_wlan_bss_regained" );
       
  1970             break;
       
  1971         case core_am_indication_wlan_wep_decrypt_failure:
       
  1972             DEBUG( "core_server_c::notify() - core_am_indication_wlan_wep_decrypt_failure" );
       
  1973             break;
       
  1974         case core_am_indication_wlan_pairwise_key_mic_failure:
       
  1975             DEBUG( "core_server_c::notify() - core_am_indication_wlan_pairwise_key_mic_failure" );
       
  1976             break;
       
  1977         case core_am_indication_wlan_group_key_mic_failure: 
       
  1978             DEBUG( "core_server_c::notify() - core_am_indication_wlan_group_key_mic_failure" );
       
  1979             break;
       
  1980         case core_am_indication_wlan_scan_complete:
       
  1981             DEBUG( "core_server_c::notify() - core_am_indication_wlan_scan_complete" );
       
  1982             break;
       
  1983         case core_am_indication_wlan_rcpi_trigger:
       
  1984             DEBUG( "core_server_c::notify() - core_am_indication_wlan_rcpi_trigger" );
       
  1985             break;
       
  1986         case core_am_indication_wlan_signal_loss_prediction:
       
  1987             DEBUG( "core_server_c::notify() - core_am_indication_wlan_signal_loss_prediction" );
       
  1988             break;
       
  1989         case core_am_indication_wlan_power_save_test_trigger:
       
  1990             DEBUG( "core_server_c::notify() - core_am_indication_wlan_power_save_test_trigger" );
       
  1991             break;       
       
  1992         case core_am_indication_os_power_standby:
       
  1993             DEBUG( "core_server_c::notify() - core_am_indication_os_power_standby" );
       
  1994             break;
       
  1995         case core_am_indication_bt_connection_established:
       
  1996             DEBUG( "core_server_c::notify() - core_am_indication_bt_connection_established" );
       
  1997             break;
       
  1998         case core_am_indication_bt_connection_disconnected:
       
  1999             DEBUG( "core_server_c::notify() - core_am_indication_bt_connection_disconnected" );
       
  2000             break;
       
  2001         case core_am_indication_voice_call_on:
       
  2002             DEBUG( "core_server_c::notify() - core_am_indication_voice_call_on" );
       
  2003             break;
       
  2004         case core_am_indication_voice_call_off:
       
  2005             DEBUG( "core_server_c::notify() - core_am_indication_voice_call_off" );
       
  2006             break;
       
  2007         default:
       
  2008             break;
       
  2009         }
       
  2010 #endif // _DEBUG
       
  2011 
       
  2012     if ( event_handler_m &&
       
  2013          event_handler_m->notify( indication ) )
       
  2014         {
       
  2015         DEBUG( "core_server_c::notify() - indication handled by the operation" );
       
  2016 
       
  2017         return;
       
  2018         }
       
  2019 
       
  2020     switch ( indication )
       
  2021         {
       
  2022         case core_am_indication_os_power_standby:
       
  2023             {
       
  2024             /**
       
  2025              * Cancel all operations including the currently executing one.
       
  2026              */
       
  2027             cancel_all_operations( true_t );
       
  2028 
       
  2029             /**
       
  2030              * Force an immediate driver unload.
       
  2031              */ 
       
  2032             queue_unload_drivers();
       
  2033 
       
  2034             break;
       
  2035             }
       
  2036         case core_am_indication_wlan_hw_failed:
       
  2037             {
       
  2038             /**
       
  2039              * Cancel all operations including the currently executing one.
       
  2040              */
       
  2041             cancel_all_operations( false_t );
       
  2042 
       
  2043             /**
       
  2044              * Force an immediate driver unload.
       
  2045              */
       
  2046             queue_unload_drivers();
       
  2047 
       
  2048             break;
       
  2049             }
       
  2050         case core_am_indication_wlan_media_disconnect:
       
  2051             {
       
  2052             /**
       
  2053              * If the current operation is connect, handle_bss_lost or protected_setup, the indication
       
  2054              * is silently ignored. Otherwise this indication is handled like a BSS lost.
       
  2055              */
       
  2056             core_operation_base_c* op = queue_m.first();
       
  2057             if( op &&
       
  2058                 op->is_executing() &&
       
  2059                 ( op->operation_type() == core_operation_handle_bss_lost ||
       
  2060                   op->operation_type() == core_operation_connect ||
       
  2061                   op->operation_type() == core_operation_protected_setup ) )
       
  2062                 {
       
  2063                 DEBUG( "core_server_c::notify() - ignoring indication" );
       
  2064                 }
       
  2065             else
       
  2066                 {
       
  2067                 schedule_roam(
       
  2068                     core_operation_handle_bss_lost_c::core_bss_lost_reason_media_disconnect );
       
  2069                 }
       
  2070 
       
  2071             break;
       
  2072             }
       
  2073         case core_am_indication_wlan_beacon_lost:
       
  2074             /** Falls through on purpose. */
       
  2075         case core_am_indication_wlan_power_mode_failure:
       
  2076             /** Falls through on purpose. */
       
  2077         case core_am_indication_wlan_tx_fail:
       
  2078             {
       
  2079             // bss_lost is only handled in infrastructure mode
       
  2080             if ( connection_data_m->iap_data().operating_mode() == core_operating_mode_infrastructure )
       
  2081                 {
       
  2082                 // send an indication to adaptation
       
  2083                 callback_m.notify(
       
  2084                     core_notification_bss_lost,
       
  2085                     0, 
       
  2086                     NULL );
       
  2087 
       
  2088                 schedule_roam(
       
  2089                     core_operation_handle_bss_lost_c::core_bss_lost_reason_bss_lost );
       
  2090                 }
       
  2091 
       
  2092             break;
       
  2093             }
       
  2094         case core_am_indication_wlan_pairwise_key_mic_failure:
       
  2095             {
       
  2096             DEBUG( "core_server_c::notify() - a pairwise MIC failure has occured" );
       
  2097 
       
  2098             mic_failure( false_t );
       
  2099             
       
  2100             break;
       
  2101             }
       
  2102         case core_am_indication_wlan_group_key_mic_failure:
       
  2103             {
       
  2104             DEBUG( "core_server_c::notify() - a group MIC failure has occured" );
       
  2105 
       
  2106             mic_failure( true_t );
       
  2107 
       
  2108             break;
       
  2109             }
       
  2110         case core_am_indication_wlan_bss_regained:
       
  2111             // Do nothing.
       
  2112             break;
       
  2113         case core_am_indication_wlan_wep_decrypt_failure:
       
  2114             // Do nothing.
       
  2115             break;
       
  2116         case core_am_indication_bt_connection_established:
       
  2117             {
       
  2118             core_settings_m.set_bt_connection_established( true_t );
       
  2119             core_operation_base_c* command = new core_operation_update_rxtx_parameters_c(
       
  2120                 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m );
       
  2121 
       
  2122             queue_int_operation_and_run_next( command );
       
  2123 
       
  2124             break;
       
  2125             }
       
  2126         case core_am_indication_bt_connection_disconnected:
       
  2127             {
       
  2128             core_settings_m.set_bt_connection_established( false_t );
       
  2129             core_operation_base_c* command = new core_operation_update_rxtx_parameters_c(
       
  2130                 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m );
       
  2131 
       
  2132             queue_int_operation_and_run_next( command );
       
  2133 
       
  2134             break;
       
  2135             }
       
  2136         case core_am_indication_wlan_scan_complete:
       
  2137             {
       
  2138             DEBUG( "core_server_c::notify() - scan complete received without pending scan operations" );
       
  2139             ASSERT( false_t );
       
  2140 
       
  2141             break;
       
  2142             }
       
  2143         case core_am_indication_wlan_rcpi_trigger:
       
  2144             {
       
  2145             if ( !is_operation_in_queue_with_type( core_operation_check_rcpi ) && 
       
  2146                  !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) )
       
  2147                 {
       
  2148                 // send an indication to adaptation
       
  2149                 callback_m.notify(
       
  2150                     core_notification_rcpi_roam_attempt_started,
       
  2151                     0, 
       
  2152                     NULL );
       
  2153 
       
  2154                 // create operation to handle the indication
       
  2155                 core_operation_base_c* command = new core_operation_check_rcpi_c(
       
  2156                     REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_operation_check_rcpi_c::core_rcpi_check_reason_rcpi_trigger );
       
  2157 
       
  2158                 queue_int_operation_and_run_next( command );
       
  2159                 }
       
  2160             else
       
  2161                 {
       
  2162                 DEBUG( "core_server_c::notify() - roaming operation already in queue " );
       
  2163                 }
       
  2164 
       
  2165             break;
       
  2166             }
       
  2167         case core_am_indication_wlan_signal_loss_prediction:
       
  2168             {
       
  2169             if ( !is_operation_in_queue_with_type( core_operation_check_rcpi ) && 
       
  2170                  !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) )
       
  2171                 {
       
  2172                 // send an indication to adaptation
       
  2173                 /*
       
  2174                 callback_m.notify(
       
  2175                     core_notification_rcpi_roam_attempt_started,
       
  2176                     0, 
       
  2177                     NULL );
       
  2178                  */
       
  2179 
       
  2180                 // create operation to handle the indication
       
  2181                 /*
       
  2182                 core_operation_base_c* command = new core_operation_check_rcpi_c(
       
  2183                     REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_operation_check_rcpi_c::core_rcpi_check_reason_signal_loss_prediction );
       
  2184 
       
  2185                 queue_int_operation_and_run_next( command, LIST_HIGH_PRIORITY );
       
  2186                  */
       
  2187                 }
       
  2188             else
       
  2189                 {
       
  2190                 DEBUG( "core_server_c::notify() - roaming operation already in queue " );
       
  2191                 }
       
  2192 
       
  2193             break;
       
  2194             }
       
  2195         case core_am_indication_wlan_power_save_test_trigger:
       
  2196             {
       
  2197             DEBUG( "core_server_c::notify() - scheduling a power save test" );
       
  2198 
       
  2199             core_operation_base_c* command = new core_operation_power_save_test_c(
       
  2200                 REQUEST_ID_CORE_INTERNAL,
       
  2201                 this,
       
  2202                 &drivers_m,
       
  2203                 &callback_m );
       
  2204 
       
  2205             queue_int_operation_and_run_next( command );
       
  2206 
       
  2207             break;
       
  2208             }
       
  2209         case core_am_indication_voice_call_on:
       
  2210             {
       
  2211             DEBUG( "core_server_c::notify() - voice call is on" );
       
  2212             connection_data_m->set_voice_call_state( true_t );
       
  2213             break;
       
  2214             }
       
  2215         case core_am_indication_voice_call_off:
       
  2216             {
       
  2217             DEBUG( "core_server_c::notify() - voice call is off" );
       
  2218             connection_data_m->set_voice_call_state( false_t );
       
  2219             break;
       
  2220             }
       
  2221         case core_am_indication_wlan_ap_ps_mode_error:
       
  2222             // Do nothing.
       
  2223             break;
       
  2224         default:
       
  2225             DEBUG( "core_server_c::notify() - unknown indication" );
       
  2226             ASSERT( false_t );
       
  2227             break;
       
  2228         }
       
  2229     }
       
  2230 
       
  2231 // ---------------------------------------------------------------------------
       
  2232 // ---------------------------------------------------------------------------
       
  2233 //    
       
  2234 void core_server_c::schedule_operation()
       
  2235     {
       
  2236     DEBUG( "core_server_c::schedule_operation()" );
       
  2237     
       
  2238     core_operation_base_c* operation = queue_m.first();
       
  2239 
       
  2240     DEBUG1( "core_server_c::schedule_operation() - %u operation(s) in the queue",
       
  2241         queue_m.count());
       
  2242 
       
  2243 #ifdef _DEBUG
       
  2244     if( operation && operation->is_executing() )
       
  2245         {
       
  2246         DEBUG2("core_server_c::schedule_operation() - operation 0x%08X (type %u) is executing",
       
  2247             operation, operation->operation_type() );
       
  2248         }
       
  2249 #endif // _DEBUG
       
  2250 
       
  2251     if( !operation &&
       
  2252         core_settings_m.connection_state() == core_connection_state_notconnected &&
       
  2253         core_settings_m.is_driver_loaded() &&
       
  2254         !driver_unload_timer_m->is_active() )
       
  2255         {
       
  2256         // If 1) no more operations and 
       
  2257         // 2) no connection exists and
       
  2258         // 3) drivers are loaded and
       
  2259         // 4) driver not already active,
       
  2260         // start unload timer
       
  2261         DEBUG( "core_server_c::schedule_operation() - starting unload timer" );
       
  2262         schedule_unload_timer(
       
  2263             device_settings_m.unload_driver_timer * SECONDS_FROM_MICROSECONDS );
       
  2264 
       
  2265         return;
       
  2266         }
       
  2267 
       
  2268     if ( operation &&
       
  2269          !operation->is_executing() &&
       
  2270          !queue_timer_m->is_active() )
       
  2271         {
       
  2272         DEBUG( "core_server_c::schedule_operation() - scheduling a new operation" );
       
  2273         queue_timer_m->start( CORE_TIMER_IMMEDIATELY );
       
  2274         }
       
  2275     }
       
  2276 
       
  2277 // ---------------------------------------------------------------------------
       
  2278 // ---------------------------------------------------------------------------
       
  2279 // 
       
  2280 bool_t core_server_c::is_cm_active()
       
  2281     {
       
  2282     return !cm_timer_m.is_wpa_allowed();
       
  2283     }
       
  2284 
       
  2285 // ---------------------------------------------------------------------------
       
  2286 // ---------------------------------------------------------------------------
       
  2287 //
       
  2288 void core_server_c::queue_ext_operation_and_run_next(
       
  2289     core_operation_base_c* operation,
       
  2290     u32_t request_id )
       
  2291     {
       
  2292     DEBUG1( "core_server_c::queue_ext_operation_and_run_next() - request id %u",
       
  2293         request_id );
       
  2294     if( !operation )
       
  2295         {
       
  2296         DEBUG( "core_server_c::queue_ext_operation_and_run_next() - no operation, completing request." );
       
  2297         callback_m.request_complete( request_id, core_error_no_memory );
       
  2298         }
       
  2299     else if ( operation->is_flags( core_operation_base_c::core_base_flag_only_one_instance ) &&
       
  2300         is_operation_in_queue_with_type( operation->operation_type() ) )
       
  2301         {
       
  2302         DEBUG( "core_server_c::queue_ext_operation_and_run_next() - only one instance allowed in the operation queue, completing request" );
       
  2303         callback_m.request_complete( request_id, core_error_ok );
       
  2304 
       
  2305         delete operation;
       
  2306         operation = NULL;
       
  2307         }
       
  2308     else
       
  2309         {
       
  2310         core_error_e ret = queue_m.append( operation );
       
  2311         if ( ret != core_error_ok )
       
  2312             {
       
  2313             DEBUG1( "core_server_c::queue_ext_operation_and_run_next() - unable to queue the request (%u)",
       
  2314                 ret );
       
  2315             callback_m.request_complete( request_id, ret );
       
  2316 
       
  2317             delete operation;
       
  2318             operation = NULL;
       
  2319             }
       
  2320         }
       
  2321  
       
  2322     schedule_operation();
       
  2323     }
       
  2324 
       
  2325 // ---------------------------------------------------------------------------
       
  2326 // ---------------------------------------------------------------------------
       
  2327 //    
       
  2328 void core_server_c::queue_timer_expired( void* this_ptr )
       
  2329     {
       
  2330     DEBUG( "core_server_c::queue_timer_expired()" );    
       
  2331     core_server_c* self = static_cast<core_server_c*>( this_ptr );
       
  2332     
       
  2333     core_operation_base_c* operation = self->queue_m.first();
       
  2334     if( !operation )
       
  2335         {
       
  2336         /**
       
  2337          * This shouldn't normally happen but it can happen if we have
       
  2338          * schedule an operation and cancel it before it has a chance to
       
  2339          * start executing.
       
  2340          */
       
  2341 
       
  2342         return;
       
  2343         }
       
  2344 
       
  2345     ASSERT( operation );
       
  2346     ASSERT( !operation->is_executing() );
       
  2347 
       
  2348     // Set operation priority in the queue to maximum
       
  2349     self->queue_m.remove( operation );
       
  2350     self->queue_m.append( operation, LIST_TOP_PRIORITY );
       
  2351     
       
  2352     // If operation says it needs drivers, stop driver unload timer
       
  2353     if( operation->is_flags( core_operation_base_c::core_base_flag_drivers_needed ) &&
       
  2354         self->driver_unload_timer_m->is_active() )
       
  2355         {
       
  2356         DEBUG( "core_server_c::queue_timer_expired() - stopping unload timer" );
       
  2357         self->cancel_unload_timer();
       
  2358         }
       
  2359     
       
  2360     core_error_e ret = operation->start_operation();
       
  2361     if( ret == core_error_request_pending )
       
  2362         {
       
  2363         DEBUG( "core_server_c::queue_timer_expired() - operation is not done yet" );
       
  2364         return;
       
  2365         }
       
  2366 
       
  2367     DEBUG1( "core_server_c::queue_timer_expired() - operation completed with code %u",
       
  2368         ret );
       
  2369 
       
  2370     if ( operation->request_id() != REQUEST_ID_CORE_INTERNAL )
       
  2371         {
       
  2372         self->callback_m.request_complete(
       
  2373             operation->request_id(),
       
  2374             ret );
       
  2375         }    
       
  2376 
       
  2377     self->queue_m.remove( operation );
       
  2378     delete operation;
       
  2379     operation = NULL;
       
  2380 
       
  2381     self->schedule_operation();
       
  2382     }
       
  2383 
       
  2384 // ---------------------------------------------------------------------------
       
  2385 // ---------------------------------------------------------------------------
       
  2386 //    
       
  2387 void core_server_c::unload_timer_expired( void* this_ptr )
       
  2388     {
       
  2389     DEBUG("core_server_c::unload_timer_expired()");
       
  2390     core_server_c* self = static_cast<core_server_c*>( this_ptr );
       
  2391 
       
  2392     /**
       
  2393      * Due to configurable unload timer value and different platform timing issues
       
  2394      * it's possible that a new operation has been added to the operation queue
       
  2395      * AFTER this timer was started but the queue timer has not yet been triggered.
       
  2396      * 
       
  2397      * Therefore we have to abort driver unloading if there's an operation in the
       
  2398      * queue that requires drivers.
       
  2399      */
       
  2400     if( self->is_operation_in_queue_with_flags(
       
  2401         core_operation_base_c::core_base_flag_drivers_needed ) )
       
  2402         {
       
  2403         DEBUG( "core_server_c::unload_timer_expired() - operation in queue, aborting driver unloading" );
       
  2404 
       
  2405         return;
       
  2406         }
       
  2407 
       
  2408     self->queue_unload_drivers();
       
  2409     }
       
  2410 
       
  2411 // ---------------------------------------------------------------------------
       
  2412 // ---------------------------------------------------------------------------
       
  2413 //
       
  2414 void core_server_c::mic_failure(
       
  2415     bool_t is_group_key_fail )
       
  2416     {
       
  2417     DEBUG( "core_server_c::mic_failure()" );
       
  2418     
       
  2419     core_connection_security_mode_e mode = core_connection_security_mode_open;
       
  2420     
       
  2421     if( core_error_ok != get_current_security_mode( mode ) )
       
  2422         {
       
  2423         DEBUG( "core_server_c::mic_failure() - not connected, ignoring mic failure" );
       
  2424         return;
       
  2425         }
       
  2426     
       
  2427     if( mode != core_connection_security_mode_wpa && 
       
  2428         mode != core_connection_security_mode_wpa_psk )
       
  2429         {
       
  2430         DEBUG( "core_server_c::mic_failure() - security mode not WPA, ignoring mic failure" );
       
  2431         return;
       
  2432         }
       
  2433 
       
  2434     if( is_group_key_fail )
       
  2435         {
       
  2436         if( connection_data_m->current_ap_data() != NULL &&
       
  2437             connection_data_m->current_ap_data()->best_group_cipher() != core_cipher_suite_tkip )
       
  2438             {
       
  2439             DEBUG( "core_server_c::mic_failure() - TKIP not the best group cipher, ignoring mic failure" );
       
  2440             return;
       
  2441             }
       
  2442         }
       
  2443     else
       
  2444         {
       
  2445         if( connection_data_m->current_ap_data() != NULL &&
       
  2446             connection_data_m->current_ap_data()->best_pairwise_cipher() != core_cipher_suite_tkip )
       
  2447             {
       
  2448             DEBUG( "core_server_c::mic_failure() - TKIP not the best pairwise cipher, ignoring mic failure" );
       
  2449             return;
       
  2450             }
       
  2451         }
       
  2452         
       
  2453     const core_mac_address_s bssid(
       
  2454         connection_data_m->current_ap_data()->bssid() );
       
  2455 
       
  2456     cm_timer_m.mic_failure();
       
  2457 
       
  2458     network_id_c network_id(
       
  2459         const_cast<u8_t*>( &bssid.addr[0] ),
       
  2460         MAC_ADDR_LEN,
       
  2461         &own_mac_addr_m.addr[0],
       
  2462         MAC_ADDR_LEN,
       
  2463         eapol_m->ethernet_type() );
       
  2464 
       
  2465     ASSERT( eapol_m );
       
  2466     (void)eapol_m->tkip_mic_failure(
       
  2467         &network_id,
       
  2468         !cm_timer_m.is_wpa_allowed() ? true_t : false_t,
       
  2469         is_group_key_fail ? wlan_eapol_if_eapol_tkip_mic_failure_type_group_key :
       
  2470             wlan_eapol_if_eapol_tkip_mic_failure_type_pairwise_key );
       
  2471 
       
  2472 
       
  2473     if ( !cm_timer_m.is_wpa_allowed() )
       
  2474         {
       
  2475         DEBUG( "core_server_c::mic_failure() - two MIC failures within 60 seconds, disconnecting" );
       
  2476                 
       
  2477         core_operation_base_c* command = new core_operation_release_c(
       
  2478             REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_release_reason_tkip_mic_failure );
       
  2479 
       
  2480         queue_int_operation_and_run_next( command );
       
  2481         }        
       
  2482     }
       
  2483 
       
  2484 // ---------------------------------------------------------------------------
       
  2485 // ---------------------------------------------------------------------------
       
  2486 //
       
  2487 void core_server_c::queue_unload_drivers()
       
  2488     {
       
  2489     DEBUG( "core_server_c::queue_unload_drivers()" );
       
  2490 
       
  2491     core_operation_base_c* command = new core_operation_unload_drivers_c(
       
  2492         REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m );
       
  2493 
       
  2494     queue_int_operation_and_run_next( command );    
       
  2495     }