--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/natplugins/natpnatfwsdpprovider/src/nspstatemachine.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,386 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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: State machine implementation.
+*
+*/
+
+#include "nspstatemachine.h"
+#include "nspstatebase.h"
+#include "nspsessiondata.h"
+#include "nspevents.h"
+#include "nspstateinitializing.h"
+#include "nspstateidle.h"
+#include "nspstatelocalcand.h"
+#include "nspstatenegotiating.h"
+#include "nspstateresolving.h"
+#include "nspstateactivating.h"
+#include "nspstateconnected.h"
+#include "nspstatedeactivating.h"
+#include "nspdefs.h"
+
+#define STATE_ID_L( statearray, state ) \
+ User::LeaveIfError( statearray.Find( state ) )
+
+#define LOGSTATE( aState ) \
+ switch( aState )\
+ {\
+ case KStateIndexInitializing:{ NSPLOG_STR( "state:Initializing" ); break; }\
+ case KStateIndexIdle:{ NSPLOG_STR( "state:Idle" ); break; }\
+ case KStateIndexLocalCand:{ NSPLOG_STR( "state:LocalCand" ); break; }\
+ case KStateIndexNegotiating:{ NSPLOG_STR( "state:Negotiating" ); break; }\
+ case KStateIndexResolving:{ NSPLOG_STR( "state:Resolving" ); break; }\
+ case KStateIndexActivating:{ NSPLOG_STR( "state:Activating" ); break; }\
+ case KStateIndexConnected:{ NSPLOG_STR( "state:Connected" ); break; }\
+ case KStateIndexDeActivating:{ NSPLOG_STR( "state:DeActivating" ); break; }\
+ default:{ NSPLOG_STR( "state:Unknown" ); break; }\
+ }
+
+#define LOGOLDSTATE( aState ) \
+ switch( aState )\
+ {\
+ case KStateIndexInitializing:{ NSPLOG_STR( " old state:Initializing" ); break; }\
+ case KStateIndexIdle:{ NSPLOG_STR( " old state:Idle" ); break; }\
+ case KStateIndexLocalCand:{ NSPLOG_STR( " old state:LocalCand" ); break; }\
+ case KStateIndexNegotiating:{ NSPLOG_STR( " old state:Negotiating" ); break; }\
+ case KStateIndexResolving:{ NSPLOG_STR( " old state:Resolving" ); break; }\
+ case KStateIndexActivating:{ NSPLOG_STR( " old state:Activating" ); break; }\
+ case KStateIndexConnected:{ NSPLOG_STR( " old state:Connected" ); break; }\
+ case KStateIndexDeActivating:{ NSPLOG_STR( " old state:DeActivating" ); break; }\
+ default:{ NSPLOG_STR( " old state:Unknown" ); break; }\
+ }
+
+#define LOGSNEWTATE( aState ) \
+ switch( aState )\
+ {\
+ case KStateIndexInitializing:{ NSPLOG_STR( " new state:Initializing" ); break; }\
+ case KStateIndexIdle:{ NSPLOG_STR( " new state:Idle" ); break; }\
+ case KStateIndexLocalCand:{ NSPLOG_STR( " new state:LocalCand" ); break; }\
+ case KStateIndexNegotiating:{ NSPLOG_STR( " new state:Negotiating" ); break; }\
+ case KStateIndexResolving:{ NSPLOG_STR( " new state:Resolving" ); break; }\
+ case KStateIndexActivating:{ NSPLOG_STR( " new state:Activating" ); break; }\
+ case KStateIndexConnected:{ NSPLOG_STR( " new state:Connected" ); break; }\
+ case KStateIndexDeActivating:{ NSPLOG_STR( " new state:DeActivating" ); break; }\
+ default:{ NSPLOG_STR( " new state:Unknown" ); break; }\
+ }
+
+
+#define LOGEVENT( aEvent ) \
+ switch( (TNSPStateMachineEvent::TRequest) aEvent.Request() )\
+ {\
+ case TNSPStateMachineEvent::ENat:{ NSPLOG_STR( "event:ENat" ); break; }\
+ case TNSPStateMachineEvent::ECreateOffer:{ NSPLOG_STR( "event:ECreateOffer" ); break; }\
+ case TNSPStateMachineEvent::EResolve:{ NSPLOG_STR( "event:EResolve" ); break; }\
+ case TNSPStateMachineEvent::EDecodeAnswer:{ NSPLOG_STR( "event:EDecodeAnswer" ); break; }\
+ case TNSPStateMachineEvent::EUpdate:{ NSPLOG_STR( "event:EUpdate" ); break; }\
+ case TNSPStateMachineEvent::EReservationStatus:{ NSPLOG_STR( "event:EReservationStatus" ); break; }\
+ case TNSPStateMachineEvent::ECloseSession:{ NSPLOG_STR( "event:ECloseSession" ); break; }\
+ default:{ NSPLOG_STR( "event:Unknown" ); break; }\
+ }
+
+// ======== MEMBER FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::CNSPStateMachine
+// ---------------------------------------------------------------------------
+//
+CNSPStateMachine::CNSPStateMachine()
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNSPStateMachine::ConstructL()
+ {
+ InitializeStateArrayL();
+ iCurrentState = iStateArray[KStateIndexInitializing];
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::InitializeStateArrayL
+// ---------------------------------------------------------------------------
+//
+void CNSPStateMachine::InitializeStateArrayL()
+ {
+ CNSPStateBase* state = NULL;
+
+ state = CNSPStateInitializing::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexInitializing ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateIdle::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexIdle ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateLocalCand::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexLocalCand ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateNegotiating::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexNegotiating ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateResolving::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexResolving ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateActivating::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexActivating ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateConnected::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexConnected ) );
+ CleanupStack::Pop( state );
+
+ state = CNSPStateDeActivating::NewLC();
+ User::LeaveIfError( iStateArray.Insert( state, KStateIndexDeActivating ) );
+ CleanupStack::Pop( state );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::NewL
+// ---------------------------------------------------------------------------
+//
+CNSPStateMachine* CNSPStateMachine::NewL()
+ {
+ CNSPStateMachine* self = CNSPStateMachine::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::NewLC
+// ---------------------------------------------------------------------------
+//
+CNSPStateMachine* CNSPStateMachine::NewLC()
+ {
+ CNSPStateMachine* self = new ( ELeave ) CNSPStateMachine();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::~CNSPStateMachine
+// ---------------------------------------------------------------------------
+//
+CNSPStateMachine::~CNSPStateMachine()
+ {
+ iStateArray.ResetAndDestroy();
+ iStateArray.Close();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::ProcessL
+// ---------------------------------------------------------------------------
+//
+void CNSPStateMachine::ProcessL( TNSPStateMachineEvent& aEvent )
+ {
+ __ASSERT_ALWAYS( iCurrentState, User::Leave( KErrTotalLossOfPrecision ) );
+
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, Entry" )
+
+ TBool accept = iCurrentState->AcceptL( aEvent );
+
+ if ( accept )
+ {
+ TNSPStateIndex currState = STATE_ID_L( iStateArray, iCurrentState );
+ aEvent.NextState() = currState;
+
+ LOGSTATE( currState );
+ LOGEVENT( aEvent );
+
+ iCurrentState->ApplyL( aEvent );
+
+ if ( currState != aEvent.NextState() )
+ {
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, Changing session state." )
+ LOGOLDSTATE( currState )
+
+ IsAcceptableStateTransitionL( aEvent.NextState() );
+
+ LOGSNEWTATE( aEvent.NextState() )
+
+ iCurrentState->ExitL( aEvent );
+ CNSPStateBase* newState = iStateArray[aEvent.NextState()];
+ TRAPD( error, newState->StateEntryL( aEvent ) );
+
+ if ( KErrNone != error )
+ {
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, StateEntryL leave!" )
+ NSPLOG_INT( "CNSPStateMachine::ProcessL, With leave code", error )
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, Reversing.." )
+ iCurrentState->Reverse( aEvent );
+ User::Leave( error );
+ }
+ else
+ {
+ iCurrentState = newState;
+ }
+ }
+ }
+ else
+ {
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, Ignoring event." )
+ }
+
+ NSPLOG_STR( "CNSPStateMachine::ProcessL, Exit" )
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::IsAcceptableStateTransitionL
+// ---------------------------------------------------------------------------
+//
+void CNSPStateMachine::IsAcceptableStateTransitionL(
+ TNSPStateIndex aStateIndex ) const
+ {
+ User::LeaveIfError( IsAcceptableStateTransition( aStateIndex ) ?
+ KErrNone : KErrArgument );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPStateMachine::IsAcceptableStateTransition
+// ---------------------------------------------------------------------------
+//
+TBool CNSPStateMachine::IsAcceptableStateTransition(
+ TNSPStateIndex aStateIndex ) const
+ {
+ const TNSPStateIndex currstate = iStateArray.Find( iCurrentState );
+
+ switch( currstate )
+ {
+ case KErrNotFound:
+ {
+ NSPLOG_STR(
+ "CNSPStateMachine::IsAcceptableStateTransition(), Not found" )
+ return EFalse;
+ }
+
+ case KStateIndexInitializing:
+ {
+ if ( KStateIndexIdle == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexIdle:
+ {
+ if ( KStateIndexLocalCand == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexLocalCand:
+ {
+ if ( KStateIndexNegotiating == aStateIndex ||
+ KStateIndexResolving == aStateIndex ||
+ KStateIndexActivating == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexNegotiating:
+ {
+ if ( KStateIndexResolving == aStateIndex ||
+ KStateIndexActivating == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexResolving:
+ {
+ if ( KStateIndexActivating == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexActivating:
+ {
+ if ( KStateIndexConnected == aStateIndex ||
+ KStateIndexDeActivating == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexConnected:
+ {
+ if ( KStateIndexLocalCand == aStateIndex ||
+ KStateIndexActivating == aStateIndex ||
+ KStateIndexResolving == aStateIndex ||
+ KStateIndexDeActivating == aStateIndex )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ case KStateIndexDeActivating:
+ {
+ return EFalse; // end state, no transitions allowed
+ }
+
+ default:
+ {
+ // never should come here,
+ // since all state transitions are handled above
+ NSPLOG_STR(
+ "CNSPStateMachine::IsAcceptableStateTransition(), DEFAULT" )
+ return EFalse;
+ }
+ }
+ }
+
+
+// end of file