wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_base.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_operation_base.cpp	Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,431 @@
+/*
+* Copyright (c) 2005-2006 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:  Base class for wlan engine operations
+*
+*/
+
+
+#include "core_operation_base.h"
+#include "core_server.h"
+#include "core_sub_operation_load_drivers.h"
+#include "am_debug.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_base_c::core_operation_base_c(
+    core_operation_type_e type,
+    u32_t request_id,
+    core_server_c* server,
+    abs_core_driverif_c* drivers,
+    abs_core_server_callback_c* adaptation,
+    u32_t feature_flags ) :
+    request_id_m( request_id ),
+    server_m( server ),
+    drivers_m( drivers ),
+    adaptation_m( adaptation ),
+    is_executing_m( false_t ),
+    is_canceling_m( false_t ),
+    operation_state_m( core_base_state_init ),
+    sub_operation_m( NULL ),
+    failure_reason_m( core_error_cancel ),
+    operation_type_m( type ),
+    feature_flags_m( feature_flags )
+    {
+    DEBUG1( "core_operation_base_c::core_operation_base_c() (%08X)",
+        this );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_base_c::~core_operation_base_c()
+    {
+    DEBUG1( "core_operation_base_c::~core_operation_base_c() (%08X)",
+        this );
+    
+    delete sub_operation_m;
+    sub_operation_m = NULL;
+    server_m = NULL;
+    drivers_m = NULL;
+    adaptation_m = NULL;
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::start_operation()
+    {
+    DEBUG1( "core_operation_base_c::start_operation() (%08X)",
+        this );
+    
+    is_executing_m = true_t;
+    return continue_operation( core_error_ok );
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::continue_operation(
+    core_error_e request_status )
+    {
+    DEBUG1( "core_operation_base_c::continue_operation() (%08X)",
+        this );
+    bool_t is_sub_operation_canceled( false_t );
+
+    /**
+     * If we have pending sub-operation, this continue must be for it.
+     */
+    if ( sub_operation_m )
+        {
+        core_error_e ret = sub_operation_m->continue_operation( request_status );
+        if ( ret == core_error_request_pending )
+            {
+            DEBUG( "core_operation_base_c::continue_operation() - sub-operation still pending" );
+            return ret;
+            }
+
+        delete sub_operation_m;
+        sub_operation_m = NULL;
+
+        if ( ret == core_error_ok )
+            {
+            DEBUG( "core_operation_base_c::continue_operation() - sub-operation completed successfully" );
+            }
+        else if ( is_canceling_m )
+            {
+            DEBUG( "core_operation_base_c::continue_operation() - sub-operation user cancel completed" );
+            is_sub_operation_canceled = true_t;
+            }
+        else
+            {
+            DEBUG1( "core_operation_base_c::continue_operation() - sub-operation failed with %u",
+                ret );
+            failure_reason_m = ret;
+
+            return cancel_operation();
+            }
+        }
+
+    /**
+     * Handle user cancel for operations that haven't overridden the user cancel method.
+     */
+    if ( operation_state_m == core_base_state_user_cancel )
+        {
+        DEBUG( "core_operation_base_c::continue_operation() - user cancel complete" );
+        ASSERT( is_canceling_m );
+
+        return core_error_cancel;
+        }
+
+    /**
+     * This continue is for this operation.
+     *
+     * If a sub-operation has just completed its user cancel, ignore the return
+     * value.
+     */    
+    if ( !is_sub_operation_canceled &&
+         request_status != core_error_ok )
+        {
+        DEBUG1( "core_operation_base_c::continue_operation() - request failed with %u",
+            request_status );
+        failure_reason_m = request_status;
+
+        return cancel_operation();
+        }
+
+    switch ( operation_state_m )
+        {
+        case core_base_state_init:
+            {
+            operation_state_m = core_base_state_next;
+
+            if ( is_flags( core_base_flag_drivers_needed ) &&
+                 !server_m->get_core_settings().is_driver_loaded() )
+                {
+                DEBUG( "core_operation_base_c::continue_operation() - drivers required" );
+                
+                operation_state_m = core_base_state_load_drivers;
+                
+                core_operation_base_c* operation = new core_sub_operation_load_drivers_c(
+                    request_id_m, server_m, drivers_m, adaptation_m );
+                return run_sub_operation( operation );
+                }
+
+            return next_state();
+            }
+        case core_base_state_load_drivers:
+            {
+            DEBUG( "core_operation_base_c::continue_operation() - drivers loaded successfully" );
+
+            operation_state_m = core_base_state_next;
+
+            return next_state();
+            }
+        default:
+            {
+            core_error_e ret = next_state(); 
+
+            /**
+             * Always return an error code when the operation completes
+             * after user cancel.
+             */
+            if( is_canceling_m &&
+                ret != core_error_request_pending )
+                {
+                DEBUG( "core_operation_base_c::continue_operation() - completing user canceled operation with core_error_cancel" );
+
+                return core_error_cancel;
+                }
+
+            return ret;
+            }
+        }
+    }       
+     
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::cancel_operation()
+    {
+    DEBUG1( "core_operation_base_c::cancel_operation() (%08X)",
+        this );
+    
+    /**
+     * If we have pending sub-operation, it must be canceled first.
+     */
+    if ( sub_operation_m )
+        {
+        core_error_e ret = sub_operation_m->cancel_operation();
+        if ( ret == core_error_request_pending )
+            {
+            DEBUG( "core_operation_base_c::cancel_operation() - sub-operation cancel pending" );
+            return ret;
+            }
+
+        delete sub_operation_m;
+        sub_operation_m = NULL;
+        }
+
+    /**
+     * If the cancel occurs during the base operation state machine, fail the operation
+     * immediately without making the main state machine handle the failure.
+     */
+    if ( operation_state_m < core_base_state_next )
+        {
+        DEBUG( "core_operation_base_c::cancel_operation() - canceling using base operation cancel()" );
+
+        return core_operation_base_c::cancel();
+        }
+
+    return cancel();
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_operation_base_c::user_cancel_operation(
+    bool_t do_graceful_cancel )
+    {
+    DEBUG1( "core_operation_base_c::user_cancel_operation() (%08X)",
+        this );
+    
+    /**
+     * Prevent double canceling.
+     */
+    if ( is_canceling_m )
+        {
+        DEBUG( "core_operation_base_c::user_cancel_operation() - canceling already in progress" );
+        
+        return;
+        }
+
+    /**
+     * If we have pending sub-operation, it must be canceled first.
+     */
+    if ( sub_operation_m )
+        {
+        sub_operation_m->user_cancel_operation( do_graceful_cancel );
+        }
+
+    is_canceling_m = true_t;
+
+    /**
+     * If the user cancel occurs during the base operation state machine, fail the operation
+     * immediately without making the main state machine handle the user cancel.
+     */
+    if ( operation_state_m < core_base_state_next )
+        {
+        DEBUG( "core_operation_base_c::user_cancel_operation() - canceling using base operation user_cancel()" );
+
+        core_operation_base_c::user_cancel( do_graceful_cancel );
+        return;
+        }
+    
+    user_cancel( do_graceful_cancel );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+u32_t core_operation_base_c::request_id() const
+    {
+    return request_id_m;
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_operation_type_e core_operation_base_c::operation_type() const
+    {
+    return operation_type_m;
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+bool_t core_operation_base_c::is_executing() const
+    {
+    return is_executing_m;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+bool_t core_operation_base_c::is_flags(
+    u32_t feature_flags ) const
+    {
+    if ( feature_flags_m & feature_flags )
+        {
+        return true_t;
+        }
+
+    return false_t;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::cancel()
+    {
+    DEBUG( "core_operation_base_c::cancel() " );
+    
+    return failure_reason_m;    
+    }        
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_operation_base_c::user_cancel(
+    bool_t /* do_graceful_cancel */ )
+    {
+    DEBUG( "core_operation_base_c::user_cancel()" );
+
+    operation_state_m = core_base_state_user_cancel;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::goto_state(
+    u32_t state )
+    {
+    operation_state_m = state;
+    
+    return next_state();
+    }
+        
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::run_sub_operation(
+    core_operation_base_c* sub_operation )
+    {
+    DEBUG( "core_operation_base_c::run_sub_operation() " );
+
+    ASSERT( !sub_operation_m );
+    sub_operation_m = sub_operation;
+
+    if ( !sub_operation_m )
+        {
+        DEBUG( "core_operation_base_c::run_sub_operation() - sub-operation creation failed" );
+        failure_reason_m = core_error_no_memory;
+                   
+        return cancel_operation();
+        }
+
+    core_error_e ret = sub_operation_m->start_operation();
+    if ( ret == core_error_request_pending )
+        {
+        DEBUG( "core_operation_base_c::run_sub_operation() - sub-operation still pending" );
+        return ret;
+        }
+
+    delete sub_operation_m;
+    sub_operation_m = NULL;
+
+    if ( ret != core_error_ok )
+        {
+        DEBUG1( "core_operation_base_c::run_sub_operation() - sub-operation failed with %u",
+            ret );
+        failure_reason_m = ret;
+        
+        return cancel_operation();               
+        }
+
+    DEBUG( "core_operation_base_c::run_sub_operation() - sub-operation completed successfully" );
+
+    return continue_operation( ret );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::run_sub_operation(
+    core_operation_base_c* sub_operation,
+    u32_t state )
+    {
+    operation_state_m = state;
+
+    return run_sub_operation( sub_operation );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+core_error_e core_operation_base_c::asynch_goto(
+    u32_t state,
+    u32_t delay )
+    {
+    operation_state_m = state;
+
+    server_m->schedule_operation_timer(
+        delay );
+        
+    return core_error_request_pending;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void core_operation_base_c::asynch_default_user_cancel()
+    {
+    DEBUG( "core_operation_base_c::asynch_default_user_cancel()" );
+
+    server_m->cancel_operation_timer();
+
+    asynch_goto( core_base_state_user_cancel );
+    }