201021
authorhgs
Tue, 25 May 2010 16:07:06 +0300
changeset 24 e717b8f55620
parent 23 2e79b4af3f09
child 25 a0fdcd0e4c56
201021
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/abs_wlan_eapol_callback_interface.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_connection_data.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_eapol_handler.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_handle_bss_lost.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_release.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_sub_operation_wpa_connect.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_wlan_eapol_if_message.h
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_connection_data.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_eapol_handler.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_handle_bss_lost.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_release.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_roam.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_wpa_connect.cpp
wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_wlan_eapol_if_message.cpp
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/abs_wlan_eapol_callback_interface.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/abs_wlan_eapol_callback_interface.h	Tue May 25 16:07:06 2010 +0300
@@ -114,6 +114,12 @@
         core_type_list_c< protected_setup_credential_c > & credential_list ) = 0;
 
     /**
+     * The complete_disassociation() function completes disassociation function.
+     */
+    virtual core_error_e complete_disassociation(
+        network_id_c * receive_network_id ) = 0;
+
+    /**
      * The handle_error() function tells about error from EAPOL side.
      */
     virtual void handle_error(
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_connection_data.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_connection_data.h	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 33 %
+* %version: 34 %
 */
 
 #ifndef CORE_CONNECTION_DATA_H
@@ -468,6 +468,23 @@
         const core_mac_address_s& bssid );
 
     /**
+     * Get the status of the ongoing authentication.
+     *
+     * @since S60 v3.1
+     * @return The status of the ongoing authentication. 
+     */
+    core_error_e eapol_auth_failure() const;
+
+    /**
+     * Set the status of the ongoing authentication.
+     *
+     * @since S60 v3.1
+     * @param error The status of the ongoing authentication. 
+     */
+    void set_eapol_auth_failure(
+        core_error_e error );
+
+    /**
      * Return the list of active traffic streams.
      *
      * @since S60 v3.2
@@ -501,6 +518,23 @@
         bool_t is_eapol_connecting );
 
     /**
+     * Check whether EAPOL is disconnecting.
+     *
+     * @since S60 v3.1
+     * @return Whether EAPOL is disconnecting.
+     */    
+    bool_t is_eapol_disconnecting() const;
+    
+    /**
+     * Set the status of EAPOL disconnecting.
+     *
+     * @since S60 v3.1
+     * @param is_eapol_disconnecting Whether EAPOL is disconnecting.
+     */
+    void set_eapol_disconnecting(
+        bool_t is_eapol_disconnecting );
+    
+    /**
      * Check whether disconnection is ongoing.
      *
      * @since S60 v3.2
@@ -751,15 +785,21 @@
     /** The BSSID currently being authenticated against. */
     core_mac_address_s eapol_auth_bssid_m;
 
+    /** Status of the currently ongoing authentication. */
+    core_error_e eapol_auth_failure_m;
+
     /** List of active traffic streams. */
     core_traffic_stream_list_c traffic_stream_list_m;
 
     /** List of virtual traffic streams. */
     core_virtual_traffic_stream_list_c virtual_traffic_stream_list_m;
-    
+
     /** Whether EAPOL is connecting. */
     bool_t is_eapol_connecting_m;
-    
+
+    /** Whether EAPOL is disconnecting. */
+    bool_t is_eapol_disconnecting_m;
+
     /** Whether disconnection is ongoing. */
     bool_t is_disconnecting_m;
 
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_eapol_handler.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_eapol_handler.h	Tue May 25 16:07:06 2010 +0300
@@ -192,6 +192,12 @@
         core_type_list_c< protected_setup_credential_c > & credential_list );
 
     /**
+     * From abs_wlan_eapol_callback_interface_c 
+     */
+    virtual core_error_e complete_disassociation(
+        network_id_c * receive_network_id );
+
+    /**
      * From abs_wlan_eapol_callback_interface_c
      */
     virtual void handle_error(
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_handle_bss_lost.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_handle_bss_lost.h	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 11 %
+* %version: 12 %
 */
 
 #ifndef CORE_OPERATION_HANDLE_BSS_LOST_H
@@ -41,6 +41,7 @@
     enum core_state_e
         {
         core_state_init = core_base_state_next,
+        core_state_eapol_disassociated,
         core_state_set_tx_level,
         core_state_set_tx_level_success,
         core_state_scan_start,
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_release.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_operation_release.h	Tue May 25 16:07:06 2010 +0300
@@ -37,6 +37,7 @@
     enum core_state_e
         {
         core_state_init = core_base_state_next,
+        core_state_eapol_disassociated,
         core_state_disable_user_data,
         core_state_tx_power_level,
         core_state_disconnect,
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_sub_operation_wpa_connect.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_sub_operation_wpa_connect.h	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 28 %
+* %version: 29 %
 */
 
 #ifndef CORE_SUB_OPERATION_WPA_CONNECT_H
@@ -65,6 +65,7 @@
         core_state_req_state_notification,
         core_state_bss_lost,
         core_state_user_cancel,
+        core_state_user_cancel_disassociated,
         core_state_MAX
         };
 
@@ -190,6 +191,12 @@
     /**
      * From abs_wlan_eapol_callback_interface_c
      */
+    core_error_e complete_disassociation(
+        network_id_c * receive_network_id );
+    
+    /**
+     * From abs_wlan_eapol_callback_interface_c
+     */
     void handle_error(
         wlan_eapol_if_error_e errorcode,
         wlan_eapol_if_message_type_function_e function );
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_wlan_eapol_if_message.h	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/inc/core_wlan_eapol_if_message.h	Tue May 25 16:07:06 2010 +0300
@@ -90,6 +90,7 @@
     wlan_eapol_if_message_type_function_update_wlan_database_reference_values       = 21,
     wlan_eapol_if_message_type_function_complete_start_wpx_fast_roam_reassociation  = 22,
     wlan_eapol_if_message_type_function_new_protected_setup_credentials             = 23,
+    wlan_eapol_if_message_type_function_complete_disassociation                     = 37
     };
 
 
@@ -752,6 +753,8 @@
     core_error_e parse_new_protected_setup_credentials(
         core_type_list_c< protected_setup_credential_c > & credential_list );
 
+    core_error_e parse_complete_disassociation(
+        network_id_c * receive_network_id );
 
     void debug_print();
     
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_connection_data.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_connection_data.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 37 %
+* %version: 38 %
 */
 
 #include "core_connection_data.h"
@@ -52,9 +52,11 @@
     is_eapol_authentication_started_m( false_t ),
     is_eapol_authenticating_m( false_t ),
     eapol_auth_bssid_m( ZERO_MAC_ADDR ),
+    eapol_auth_failure_m( core_error_ok ),
     traffic_stream_list_m( ),
     virtual_traffic_stream_list_m( ),
     is_eapol_connecting_m( false_t ),
+    is_eapol_disconnecting_m( false_t ),
     is_disconnecting_m( false_t ),
     last_roam_reason_m( core_roam_reason_none ),
     last_roam_failed_reason_m( core_roam_failed_reason_none ),
@@ -672,6 +674,23 @@
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 //
+core_error_e core_connection_data_c::eapol_auth_failure() const
+    {
+    return eapol_auth_failure_m;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_connection_data_c::set_eapol_auth_failure(
+    core_error_e error )
+    {
+    eapol_auth_failure_m = error;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
 core_traffic_stream_list_c& core_connection_data_c::traffic_stream_list()
     {
     return traffic_stream_list_m;
@@ -705,6 +724,23 @@
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 //
+bool_t core_connection_data_c::is_eapol_disconnecting() const
+    {
+    return is_eapol_disconnecting_m;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_connection_data_c::set_eapol_disconnecting(
+    bool_t is_eapol_disconnecting )
+    {
+    is_eapol_disconnecting_m = is_eapol_disconnecting;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
 bool_t core_connection_data_c::is_disconnecting() const
     {
     return is_disconnecting_m;
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_eapol_handler.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_eapol_handler.cpp	Tue May 25 16:07:06 2010 +0300
@@ -110,6 +110,17 @@
             send_unencrypted );
         }
 
+    if ( !server_m->get_connection_data()->current_ap_data() )
+        {
+        /**
+         * EAPOL might try to send packets after a failed connection attempt,
+         * filter them out. This check is only valid when no handler is registered.
+         */
+        DEBUG( "core_eapol_handler_c::packet_send() - not connected or attempting connection, ignoring" );
+
+        return core_error_ok;
+        }
+
     server_m->send_data_frame(
         *server_m->get_connection_data()->current_ap_data(),
         core_frame_type_ethernet,
@@ -582,6 +593,20 @@
                 }
             break;
             }
+        case wlan_eapol_if_message_type_function_complete_disassociation:
+            {
+            network_id_c network_id( NULL, 0, NULL, 0, 0 );
+            
+            error = function.parse_complete_disassociation(
+                &network_id );
+            if ( error == core_error_ok )
+                {
+                error = complete_disassociation(
+                    &network_id );
+                }
+            break;
+
+            }
         case wlan_eapol_if_message_type_function_none:
         default:
             DEBUG1( "core_eapol_handler_c::send_data() - Error: unknown function %i", func );
@@ -853,6 +878,69 @@
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 //
+core_error_e core_eapol_handler_c::complete_disassociation(
+    network_id_c * receive_network_id )
+    {
+    DEBUG( "core_eapol_handler_c::complete_disassociation()" );
+
+    if( !server_m->get_connection_data() ||
+        !server_m->get_connection_data()->is_eapol_disconnecting() )
+        {
+        DEBUG( "core_eapol_handler_c::handle_wlan_authentication_state() - complete_disassociation received while not disconnecting, ignoring" );
+
+        return core_error_general;
+        }
+
+    const core_mac_address_s cur_bssid(
+        server_m->get_connection_data()->eapol_auth_bssid() );
+    const core_mac_address_s bssid(
+        receive_network_id->source() );
+    DEBUG6( "core_eapol_handler_c::complete_disassociation() - function BSSID is %02X:%02X:%02X:%02X:%02X:%02X",
+        bssid.addr[0], bssid.addr[1], bssid.addr[2], 
+        bssid.addr[3], bssid.addr[4], bssid.addr[5] );
+    DEBUG6( "core_eapol_handler_c::complete_disassociation() - current BSSID is %02X:%02X:%02X:%02X:%02X:%02X",
+        cur_bssid.addr[0], cur_bssid.addr[1], cur_bssid.addr[2], 
+        cur_bssid.addr[3], cur_bssid.addr[4], cur_bssid.addr[5] );
+    DEBUG1( "core_eapol_handler_c::complete_disassociation() - EAPOL authentication failure status is %u",
+        server_m->get_connection_data()->eapol_auth_failure() );
+
+    bool_t is_eapol_authentication_started(
+        server_m->get_connection_data()->is_eapol_authentication_started() );
+    DEBUG( "core_eapol_handler_c::complete_disassociation() - marking is_eapol_authenticating as false" );
+    server_m->get_connection_data()->set_eapol_authenticating(
+        false_t );
+    DEBUG( "core_eapol_handler_c::complete_disassociation() - marking is_eapol_authentication_started as false" );
+    server_m->get_connection_data()->set_eapol_authentication_started(
+        false_t );
+    DEBUG( "core_eapol_handler_c::complete_disassociation() - marking is_eapol_disconnecting as false" );
+    server_m->get_connection_data()->set_eapol_disconnecting(
+        false_t );
+
+    /**
+     * We only care about the pending status notification in case the authentication
+     * has been started by us, otherwise we'll just ignore it. 
+     */
+    if ( is_eapol_authentication_started )
+        {
+        DEBUG( "core_eapol_handler_c::complete_disassociation() - completing request" );
+        server_m->request_complete(
+            REQUEST_ID_CORE_INTERNAL,
+            server_m->get_connection_data()->eapol_auth_failure() );
+        }
+    else
+        {
+        DEBUG( "core_eapol_handler_c::complete_disassociation() - completing request (authentication not started)" );
+        server_m->request_complete(
+            REQUEST_ID_CORE_INTERNAL,
+            core_error_ok );
+        }
+
+    return core_error_ok;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
 void core_eapol_handler_c::handle_error(
     wlan_eapol_if_error_e errorcode,
     wlan_eapol_if_message_type_function_e function )
@@ -974,8 +1062,18 @@
         return;
         }
 
+    server_m->get_connection_data()->set_eapol_auth_failure(
+        eapol_wlan_authentication_state_to_error( state )  );
+
+    if ( server_m->get_connection_data()->is_eapol_disconnecting() )
+        {
+        DEBUG( "core_ap_data_c::instance() - disassociation pending, request cannot be completed yet" );
+
+        return;
+        }
+
     bool_t is_authentication_started( server_m->get_connection_data()->is_eapol_authenticating() );
-    
+
     DEBUG( "core_eapol_handler_c::handle_wlan_authentication_state() - marking is_eapol_authenticating as false" );
     server_m->get_connection_data()->set_eapol_authenticating(
         false_t );
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_handle_bss_lost.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_handle_bss_lost.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 33 %
+* %version: 34 %
 */
 
 #include "core_operation_handle_bss_lost.h"
@@ -151,34 +151,6 @@
                 }
 
             /**
-             * If the connection is lost when EAPOL is doing (re-)authentication,
-             * EAPOL must be notified.
-             */
-            if ( server_m->get_connection_data()->is_eapol_authenticating() &&
-                 ( server_m->get_connection_data()->iap_data().is_eap_used() ||
-                   server_m->get_connection_data()->iap_data().is_wapi_used() ) )
-                {
-                network_id_c network_id(
-                    &bssid.addr[0],
-                    MAC_ADDR_LEN,
-                    &server_m->own_mac_addr().addr[0],
-                    MAC_ADDR_LEN,
-                    server_m->get_eapol_instance().ethernet_type() );
-
-                DEBUG( "core_operation_handle_bss_lost_c::next_state() - marking is_eapol_authenticating as false" );
-                server_m->get_connection_data()->set_eapol_authenticating(
-                    false_t );
-
-                DEBUG6( "core_operation_handle_bss_lost_c::next_state() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
-                    bssid.addr[0], bssid.addr[1], bssid.addr[2],
-                    bssid.addr[3], bssid.addr[4], bssid.addr[5] );
-
-                server_m->get_eapol_instance().disassociation( &network_id );
-                }
-
-            operation_state_m = core_state_set_tx_level;            
-
-            /**
              * Check the channels that were previously reported to be active.
              */
             server_m->get_scan_list().get_channels_by_ssid(
@@ -201,6 +173,47 @@
             server_m->get_scan_list().remove_entries_by_bssid(
                 bssid );
 
+            /**
+             * If the connection is lost when EAPOL is doing (re-)authentication,
+             * EAPOL must be notified.
+             */
+            if ( ( server_m->get_connection_data()->is_eapol_authenticating() ||
+                   reason_m == core_bss_lost_reason_failed_reauthentication ) &&
+                 ( server_m->get_connection_data()->iap_data().is_eap_used() ||
+                   server_m->get_connection_data()->iap_data().is_wapi_used() ) )
+                {
+                network_id_c network_id(
+                    &bssid.addr[0],
+                    MAC_ADDR_LEN,
+                    &server_m->own_mac_addr().addr[0],
+                    MAC_ADDR_LEN,
+                    server_m->get_eapol_instance().ethernet_type() );
+
+                DEBUG( "core_operation_handle_bss_lost_c::next_state() - marking is_eapol_authenticating as false" );
+                server_m->get_connection_data()->set_eapol_authenticating(
+                    false_t );
+
+                DEBUG6( "core_operation_handle_bss_lost_c::next_state() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
+                    bssid.addr[0], bssid.addr[1], bssid.addr[2],
+                    bssid.addr[3], bssid.addr[4], bssid.addr[5] );
+                DEBUG( "core_operation_handle_bss_lost_c::next_state() - marking is_eapol_disconnecting as true" );
+                server_m->get_connection_data()->set_eapol_disconnecting(
+                    true );
+                server_m->get_connection_data()->set_eapol_auth_failure(
+                    core_error_eapol_failure );
+
+                server_m->get_eapol_instance().disassociation( &network_id );
+                operation_state_m = core_state_eapol_disassociated;
+
+                return core_error_request_pending;
+                }
+
+            return goto_state( core_state_eapol_disassociated );
+            }            
+        case core_state_eapol_disassociated:
+            {            
+            operation_state_m = core_state_set_tx_level;            
+
             server_m->get_core_settings().roam_metrics().set_roam_ts_userdata_disabled();
 
             drivers_m->disable_user_data(
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_release.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_release.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 17 %
+* %version: 18 %
 */
 
 #include "core_operation_release.h"
@@ -175,10 +175,21 @@
                 DEBUG6( "core_operation_release_c::next_state() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
                     bssid.addr[0], bssid.addr[1], bssid.addr[2],
                     bssid.addr[3], bssid.addr[4], bssid.addr[5] );
+                DEBUG( "core_operation_release_c::next_state() - marking is_eapol_disconnecting as true" );
+                server_m->get_connection_data()->set_eapol_disconnecting(
+                    true );
 
                 server_m->get_eapol_instance().disassociation( &network );
+                operation_state_m = core_state_eapol_disassociated;
+
+                return core_error_request_pending;
                 }
 
+            return goto_state( core_state_eapol_disassociated );
+            }
+        case core_state_eapol_disassociated:
+            {
+            DEBUG( "core_operation_release_c::next_state() - core_state_eapol_disassociated" );
             // disable user data
             drivers_m->disable_user_data( request_id_m );
             operation_state_m = core_state_disable_user_data;
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_roam.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_roam.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 76.1.2 %
+* %version: 76.1.3 %
 */
 
 #include "core_operation_roam.h"
@@ -433,6 +433,12 @@
                         bssid.addr[0], bssid.addr[1], bssid.addr[2],
                         bssid.addr[3], bssid.addr[4], bssid.addr[5] );
 
+                    /**
+                     * is_eapol_disconnecting is not updated here because this disassociation
+                     * is for the previous AP and thus we don't really care when this
+                     * request gets completed.
+                     */
+
                     server_m->get_eapol_instance().disassociation( &network );
                     }
                 }
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_wpa_connect.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_wpa_connect.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 59 %
+* %version: 59.1.1 %
 */
 
 #include "core_sub_operation_wpa_connect.h"
@@ -102,6 +102,8 @@
                 true_t );
             server_m->get_connection_data()->set_eapol_auth_bssid(
                 ZERO_MAC_ADDR );
+            server_m->get_connection_data()->set_eapol_auth_failure(
+                core_error_ok );
 
             eapol_auth_type_m = core_tools_c::eap_authentication_type(
                 server_m->get_connection_data()->iap_data(),
@@ -634,9 +636,17 @@
             DEBUG6( "core_sub_operation_wpa_connect_c::next_state() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
                 current_bssid_m.addr[0], current_bssid_m.addr[1], current_bssid_m.addr[2],
                 current_bssid_m.addr[3], current_bssid_m.addr[4], current_bssid_m.addr[5] );
+            DEBUG( "core_sub_operation_wpa_connect_c::next_state() - marking is_eapol_disconnecting as true" );
+            server_m->get_connection_data()->set_eapol_disconnecting(
+                true );
 
             server_m->get_eapol_instance().disassociation( &network );
-
+            operation_state_m = core_state_user_cancel_disassociated;
+            
+            break;
+            }
+        case core_state_user_cancel_disassociated:
+            {
             /** The connection attempt failed, we are no longer connected. */
             is_connected_m = false_t;            
 
@@ -770,10 +780,28 @@
 // ---------------------------------------------------------------------------
 //
 core_error_e core_sub_operation_wpa_connect_c::disassociate(
-    network_id_c * /*receive_network_id*/,
+    network_id_c * receive_network_id,
     const bool_t /* self_disassociation */ )
     {
     DEBUG( "core_sub_operation_wpa_connect_c::disassociate()" );
+
+    const core_mac_address_s bssid(
+        receive_network_id->source() );
+    DEBUG6( "core_sub_operation_wpa_connect_c::disassociate() - function BSSID is %02X:%02X:%02X:%02X:%02X:%02X",
+        bssid.addr[0], bssid.addr[1], bssid.addr[2], 
+        bssid.addr[3], bssid.addr[4], bssid.addr[5] );
+    DEBUG6( "core_sub_operation_wpa_connect_c::disassociate() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
+        current_bssid_m.addr[0], current_bssid_m.addr[1], current_bssid_m.addr[2],
+        current_bssid_m.addr[3], current_bssid_m.addr[4], current_bssid_m.addr[5] );
+    if( operation_state_m == core_state_req_state_notification &&
+        bssid == current_bssid_m )
+        {
+        DEBUG( "core_sub_operation_wpa_connect_c::disassociate() - marking is_eapol_disconnecting as true" );
+        server_m->get_connection_data()->set_eapol_disconnecting(
+            true );
+
+        server_m->get_eapol_instance().disassociation( receive_network_id );
+        }
     
     return core_error_ok;
     }
@@ -932,6 +960,18 @@
     return core_error_ok;
     }
 
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_sub_operation_wpa_connect_c::complete_disassociation(
+    network_id_c * /* receive_network_id */ )
+    {
+    DEBUG( "core_sub_operation_wpa_connect_c::complete_disassociation()" );
+
+    ASSERT( false_t );
+
+    return core_error_ok;
+    }
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
@@ -960,9 +1000,10 @@
 
             asynch_goto( core_state_init, CORE_TIMER_IMMEDIATELY );
             }
-        else if ( function == wlan_eapol_if_message_type_function_complete_association
+        else if ( ( function == wlan_eapol_if_message_type_function_complete_association
                || function == wlan_eapol_if_message_type_function_complete_reassociation
-               || function == wlan_eapol_if_message_type_function_complete_wpx_fast_roam_reassociation  )
+               || function == wlan_eapol_if_message_type_function_complete_wpx_fast_roam_reassociation  ) &&
+               eapol_auth_type_m == wlan_eapol_if_eapol_key_authentication_type_wpx_fast_roam )
             {
             DEBUG( "core_sub_operation_wpa_connect_c::handle_error() - (WPX fast-roam) (re-)association failed" );
             asynch_goto( core_state_req_association_failed, CORE_TIMER_IMMEDIATELY );
@@ -1011,23 +1052,14 @@
         DEBUG6( "core_sub_operation_wpa_connect_c::notify() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X",
             current_bssid_m.addr[0], current_bssid_m.addr[1], current_bssid_m.addr[2],
             current_bssid_m.addr[3], current_bssid_m.addr[4], current_bssid_m.addr[5] );
+        DEBUG( "core_sub_operation_wpa_connect_c::next_state() - marking is_eapol_disconnecting as true" );
+        server_m->get_connection_data()->set_eapol_disconnecting(
+            true );
+        server_m->get_connection_data()->set_eapol_auth_failure(
+            core_error_eapol_failure );
 
         server_m->get_eapol_instance().disassociation( &network );
 
-        if ( indication != core_am_indication_wlan_media_disconnect )
-            {
-            DEBUG( "core_sub_operation_wpa_connect_c::notify() - marking is_eapol_authenticating as false" );
-            server_m->get_connection_data()->set_eapol_authenticating(
-                false_t );
-            DEBUG( "core_sub_operation_wpa_connect_c::notify() - marking is_eapol_authentication_started as false" );
-            server_m->get_connection_data()->set_eapol_authentication_started(
-                false_t );
-
-            asynch_goto( core_state_bss_lost );
-
-            return true_t;
-            }
-
         /**
          * EAPOL indication will move the state machine forward.
          */
--- a/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_wlan_eapol_if_message.cpp	Tue May 25 15:11:14 2010 +0300
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_wlan_eapol_if_message.cpp	Tue May 25 16:07:06 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 13 %
+* %version: 14 %
 */
 
 #include "core_wlan_eapol_if_message.h"
@@ -4059,4 +4059,43 @@
     return core_error_ok;
     }
 
-
+core_error_e core_wlan_eapol_if_function_c::parse_complete_disassociation(
+    network_id_c * receive_network_id )
+    {
+    DEBUG( "core_wlan_eapol_if_function_c::parse_complete_disassociation()" );
+    ASSERT( receive_network_id );
+
+    core_error_e error( core_error_ok );
+
+    first();
+    if ( is_done() )
+        {
+        DEBUG( "core_wlan_eapol_if_function_c::parse_complete_disassociation() - message is empty" );
+        return core_error_not_found;
+        }
+
+    // Check function
+    if ( current()->get_parameter_type() != wlan_eapol_if_message_type_function )
+        {
+        return core_error_not_found;
+        }
+
+    u32_t function_value(0);
+    current()->get_parameter_data( &function_value );
+    wlan_eapol_if_message_type_function_e func( static_cast<wlan_eapol_if_message_type_function_e>( function_value ) );
+    if ( func != wlan_eapol_if_message_type_function_complete_disassociation )
+        {
+        return core_error_not_found;
+        }
+    
+    next();
+
+    // Check function parameters
+    error = parse_network_id( receive_network_id );
+    if ( error != core_error_ok )
+        {
+        return error;
+        }
+
+    return core_error_ok;
+    }