wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_roam_scan.cpp
changeset 0 c40eb8fe8501
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_roam_scan.cpp	Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,317 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Statemachine for doing scans when roaming
+*
+*/
+
+/*
+* %version: 22 %
+*/
+
+#include "core_sub_operation_roam_scan.h"
+#include "core_frame_dot11.h"
+#include "core_server.h"
+#include "core_tools_parser.h"
+#include "core_tools.h"
+#include "am_debug.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_sub_operation_roam_scan_c::core_sub_operation_roam_scan_c(
+    u32_t request_id,
+    core_server_c* server,
+    abs_core_driverif_c* drivers,
+    abs_core_server_callback_c* adaptation,
+    const core_ssid_s& scan_ssid,
+    const core_scan_channels_s& scan_channels,
+    bool_t is_connected,
+    bool_t is_first_match_selected ) :    
+    core_operation_base_c( core_operation_scan, request_id, server, drivers, adaptation,
+        core_base_flag_drivers_needed ),
+    scan_ssid_m( scan_ssid ),
+    scan_channels_m( scan_channels ),
+    is_connected_m( is_connected ),
+    is_first_match_selected( is_first_match_selected )
+    {
+    DEBUG( "core_sub_operation_roam_scan_c::core_sub_operation_roam_scan_c()" );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_sub_operation_roam_scan_c::~core_sub_operation_roam_scan_c()
+    {
+    DEBUG( "core_sub_operation_roam_scan_c::~core_sub_operation_roam_scan_c()" );
+
+    server_m->unregister_event_handler( this );
+    server_m->unregister_frame_handler( this );    
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_sub_operation_roam_scan_c::next_state()
+    {
+    DEBUG( "core_sub_operation_roam_scan_c::next_state()" );
+
+    switch ( operation_state_m )
+        {
+        case core_state_init:
+            {                        
+            operation_state_m = core_state_scan_start;
+
+            if ( scan_ssid_m.length )
+                {
+                DEBUG1S( "core_sub_operation_roam_scan_c::next_state() - requesting a direct scan with SSID ",
+                    scan_ssid_m.length, &scan_ssid_m.ssid[0] );
+                }
+            else
+                {
+                DEBUG( "core_sub_operation_roam_scan_c::next_state() - requesting a broadcast scan" );
+                }
+
+            if ( is_connected_m )
+                {
+                DEBUG( "core_sub_operation_roam_scan_c::next_state() - requesting a split-scan" );
+                }
+            else
+                {
+                DEBUG( "core_sub_operation_roam_scan_c::next_state() - requesting a regular scan" );
+                }
+
+            DEBUG2( "core_sub_operation_roam_scan_c::next_state() - requesting scan on channels 0x%02X%02X",
+                scan_channels_m.channels2dot4ghz[1],
+                scan_channels_m.channels2dot4ghz[0] );
+
+            server_m->get_scan_list().remove_entries_by_age(
+                server_m->get_device_settings().scan_list_expiration_time );
+
+            server_m->register_event_handler( this );
+            server_m->register_frame_handler( this );
+
+            drivers_m->scan(
+                request_id_m,
+                core_scan_mode_active,
+                scan_ssid_m,
+                server_m->get_device_settings().scan_rate,
+                server_m->get_core_settings().valid_scan_channels( scan_channels_m ),
+                server_m->get_device_settings().active_scan_min_ch_time,
+                server_m->get_device_settings().active_scan_max_ch_time,
+                is_connected_m );            
+
+            break;
+            }
+        case core_state_scan_start:
+            {
+            operation_state_m = core_state_scan_started;
+
+            DEBUG( "core_sub_operation_roam_scan_c::next_state() - scan start completed, waiting for scan completion" );
+
+            break;
+            }
+        case core_state_scan_stop:
+            {
+            operation_state_m = core_state_scan_stopped;
+
+            DEBUG( "core_sub_operation_roam_scan_c::next_state() - scan stop completed, waiting for scan completion" );
+
+            break;
+            }
+        case core_state_scan_stopped:
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::next_state() - invalid state transition in core_state_scan_stopped" );
+            ASSERT( false_t );
+            }
+        case core_state_scan_complete:
+            {
+            server_m->unregister_frame_handler( this );
+
+            return core_error_ok;
+            }
+        default:
+            {
+            ASSERT( false_t );
+            }
+        }
+
+    return core_error_request_pending;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_sub_operation_roam_scan_c::user_cancel(
+    bool_t do_graceful_cancel )
+    {
+    DEBUG( "core_sub_operation_roam_scan_c::user_cancel()" );
+
+    if ( !do_graceful_cancel )
+        {
+        /**
+         * If we are in a middle of a scan, we have to schedule our own
+         * event.
+         */
+        if ( operation_state_m == core_state_scan_started )
+            {
+            asynch_default_user_cancel();
+    
+            return;
+            }
+    
+        /**
+         * Everything else is handled by the default implementation.
+         */
+        core_operation_base_c::user_cancel( do_graceful_cancel );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//    
+bool_t core_sub_operation_roam_scan_c::receive_frame(
+    const core_frame_dot11_c* frame,
+    u8_t rcpi )
+    {
+    DEBUG( "core_sub_operation_roam_scan_c::receive_frame()" );
+    
+    if ( frame->type() != core_frame_dot11_c::core_dot11_type_beacon &&
+         frame->type() != core_frame_dot11_c::core_dot11_type_probe_resp )
+        {
+        DEBUG( "core_sub_operation_roam_scan_c::receive_frame() - not a beacon or a probe" );        
+        return false_t;
+        }
+
+    core_ap_data_c* ap_data = core_ap_data_c::instance(
+        server_m->get_wpx_adaptation_instance(),
+        frame,
+        rcpi,
+        false_t );
+    if ( ap_data )
+        {        
+        const core_ssid_s ssid(
+            ap_data->ssid() );
+
+#ifdef _DEBUG
+        DEBUG1S( "core_sub_operation_roam_scan_c::receive_frame() - SSID: ",
+            ssid.length, &ssid.ssid[0] );
+
+        const core_mac_address_s bssid(
+            ap_data->bssid() );
+        DEBUG6( "core_sub_operation_roam_scan_c::receive_frame() - 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] ); 
+#endif // _DEBUG
+
+        server_m->get_scan_list().update_entry( *ap_data );
+
+        /**
+         * The current implementation assumes that scan is only stopped
+         * in an emergency situation so there's no need to check for
+         * admission control parameters.
+         */
+        if ( operation_state_m == core_state_scan_started &&
+             is_first_match_selected &&
+             scan_ssid_m == ssid &&
+             core_tools_parser_c::is_ap_suitable(
+                 server_m->get_wpx_adaptation_instance(),
+                 *ap_data,
+                 server_m->get_connection_data()->iap_data(),
+                 server_m->get_core_settings(),
+                 *server_m->get_connection_data(),
+                 server_m->get_device_settings().scan_stop_rcpi_threshold,
+                 MEDIUM_TIME_NOT_DEFINED,
+                 server_m->is_cm_active(),
+                 ZERO_MAC_ADDR ) == core_connect_ok )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::receive_frame() - AP is suitable, requesting scan to be stopped" );
+
+            operation_state_m = core_state_scan_stop;
+
+            drivers_m->stop_scan(
+                request_id_m );
+            }
+        else if ( operation_state_m == core_state_scan_start )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::receive_frame() - scan frame received while starting scan" );        
+            }
+        else if ( operation_state_m == core_state_scan_stop )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::receive_frame() - scan frame received while stopping scan" );
+            }
+        else if ( operation_state_m == core_state_scan_stopped )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::receive_frame() - scan frame after scan was stopped" );
+            }
+
+        delete ap_data;
+        ap_data = NULL;
+        }
+
+    return true_t;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+bool_t core_sub_operation_roam_scan_c::notify(
+    core_am_indication_e indication )
+    {
+    if ( indication == core_am_indication_wlan_scan_complete )
+        {
+        server_m->unregister_event_handler( this );
+        
+        if ( operation_state_m == core_state_scan_start )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::notify() - scan complete received while starting scan" );
+
+            /**
+             * No need to do anything here, state will be changed when the request completes.
+             */
+            operation_state_m = core_state_scan_complete;            
+            }
+        else if ( operation_state_m == core_state_scan_started )
+            {            
+            DEBUG( "core_sub_operation_roam_scan_c::notify() - scan complete" );
+
+            asynch_goto( core_state_scan_complete, CORE_TIMER_IMMEDIATELY );
+            }
+        else if ( operation_state_m == core_state_scan_stop )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::notify() - scan complete received while stopping scan" );
+
+            /**
+             * No need to do anything here, state will be changed when the request completes.
+             */
+            operation_state_m = core_state_scan_complete;
+            }
+        else if ( operation_state_m == core_state_scan_stopped )
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::notify() - scan complete after scan stop completed" );
+
+            asynch_goto( core_state_scan_complete, CORE_TIMER_IMMEDIATELY );           
+            }        
+        else
+            {
+            DEBUG( "core_sub_operation_roam_scan_c::notify() - scan complete in unknown state" );
+            ASSERT( false_t );
+            }
+
+        return true_t;
+        }
+
+    return false_t;
+    }