--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bearermanagement/S60MCPR/src/s60mcprerrorrecoveryactivity.cpp Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,365 @@
+/*
+* Copyright (c) 2009 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: S60 MCPR error recovery activity implementation
+*
+*/
+
+/**
+@file s60mcprerrorrecoveryactivity.cpp
+S60 MCPR error recovery activity implementation
+*/
+
+#include "s60mcpractivities.h"
+#include "s60mcprstates.h"
+
+using namespace Messages;
+using namespace MeshMachine;
+using namespace ESock;
+
+// -----------------------------------------------------------------------------
+// S60MCprErrorRecoveryActivity
+// -----------------------------------------------------------------------------
+//
+namespace S60MCprErrorRecoveryActivity
+ {
+ TBool THandshakingMobilityMutex::IsBlocked(TNodeContextBase& aContext)
+ {
+ return static_cast<CS60MetaConnectionProvider&>(aContext.iNode).IsHandshakingNow();
+ }
+
+
+ // -----------------------------------------------------------------------------
+ // TSendIgnoreRecoveryResponse::DoL
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT( TSendIgnoreRecoveryResponse, NetStateMachine::MStateTransition, TContext )
+ void TSendIgnoreRecoveryResponse::DoL() // codescanner::leave
+ {
+ CS60ConnectionRecoveryActivity* ac =
+ static_cast<CS60ConnectionRecoveryActivity*>(iContext.iNodeActivity);
+
+ S60MCPRLOGSTRING2("S60MCPR<%x>::TSendIgnoreRecoveryResponse::DoL() Ignore Error %d",
+ (TInt*)&iContext.Node(),ac->iOriginalErrContext.iStateChange.iError );
+
+ __ASSERT_DEBUG( iContext.iNodeActivity, User::Panic( KS60MCprPanic, KPanicNoActivity ) );
+ TEErrorRecovery::TErrorRecoveryResponse err( TErrResponse( TErrResponse::EIgnore,
+ KErrNone,
+ ac->iOriginalErrContext.iMessageId ) );
+ // We must clear out the activity error to prevent last automatic error message from the node.
+ iContext.iNodeActivity->SetError( KErrNone );
+ ac->ReplyToOriginators( err );
+ }
+
+ // -----------------------------------------------------------------------------
+ // TAwaitingNotGoneDownErrorRecoveryRequest::Accept
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT(TAwaitingNotGoneDownErrorRecoveryRequest,
+ NetStateMachine::MState,
+ TContext)
+ TBool TAwaitingNotGoneDownErrorRecoveryRequest::Accept()
+ {
+ TEErrorRecovery::TErrorRecoveryRequest* msg =
+ message_cast<TEErrorRecovery::TErrorRecoveryRequest>(&iContext.iMessage);
+ // Validata error recovery request.
+ // This state will accept other error recovery request besides the one meant for GoneDown.
+ //
+ if ( msg )
+ {
+ TErrContext& errCtx = msg->iErrContext;
+/* if (errCtx.iActivitySigId == ECFActivityNoBearer || errCtx.iActivitySigId == ECFActivityStart
+ || errCtx.iStateChange.iError == KErrCouldNotConnect)
+*/
+ if ( errCtx.iActivitySigId != ECFActivityGoneDown )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingNotGoneDownErrorRecoveryRequest::Accept()",(TInt*)&iContext.Node());
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+ // -----------------------------------------------------------------------------
+ // TNoTagOrIgnoreErrorOrErrorTag::TransitionTag
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT(TNoTagOrIgnoreErrorOrErrorTag, NetStateMachine::MStateFork, TContext)
+ TInt TNoTagOrIgnoreErrorOrErrorTag::TransitionTag()
+ {
+ TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg* msg = NULL;
+
+ if ( iContext.iMessage.IsMessage<TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg>() )
+ {
+ msg = message_cast<TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg>(&iContext.iMessage);
+ }
+
+ // Sanity check.
+ if ( iContext.iMessage.IsMessage<TEBase::TError>() && iContext.iNodeActivity->Error() == KErrNone )
+ {
+ // Should never end up here!!
+ __ASSERT_DEBUG( EFalse, User::Panic( KS60MCprPanic, KPanicUnsupportedMCPRState ) );
+ iContext.iNodeActivity->SetError( KErrGeneral );
+ }
+
+ // Error transition
+ //
+ if ( !msg )
+ {
+ return KErrorTag | NetStateMachine::EForward;
+ }
+ // Transition to ignore error
+ //
+ else if ( (TBMNeededAction)msg->iValue == EIgnoreError )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrIgnoreErrorOrErrorTag::TransitionTag() KIgnoreError",(TInt*)&iContext.Node());
+ return S60MCprStates::KIgnoreError | NetStateMachine::EForward;
+ }
+ // Transition to reselection
+ //
+ else
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrIgnoreErrorOrErrorTag::TransitionTag() KNoTag",(TInt*)&iContext.Node());
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // TNoTagOrRetryConnectionTagOrErrorTag::TransitionTag
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT(TNoTagOrRetryConnectionTagOrErrorTag, NetStateMachine::MStateFork, TContext)
+ TInt TNoTagOrRetryConnectionTagOrErrorTag::TransitionTag()
+ {
+ CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
+ TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg* msg = NULL;
+ if ( iContext.iMessage.IsMessage<TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg>() )
+ {
+ msg = message_cast<TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg>(&iContext.iMessage);
+ }
+
+ if ( !msg )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrRetryConnectionTagOrErrorTag::TransitionTag() KErrorTag",(TInt*)&iContext.Node());
+ return KErrorTag | NetStateMachine::EForward;
+ }
+ else if ( ((RMetaServiceProviderInterface*)node.ServiceProvider())
+ ->ProviderInfo().APId() == node.PolicyPrefs().IapId() )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrRetryConnectionTagOrErrorTag::TransitionTag() KRetryConnection",(TInt*)&iContext.Node());
+ return S60MCprStates::KRetryConnection | NetStateMachine::EForward;
+ }
+ else
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrRetryConnectionTagOrErrorTag::TransitionTag() KNoTag",(TInt*)&iContext.Node());
+ return KNoTag | NetStateMachine::EForward;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // TRetryConnectionOrErrorTag::TransitionTag
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT(TRetryConnectionOrProcessErrorTagBackward, NetStateMachine::MStateFork, TContext)
+ TInt TRetryConnectionOrProcessErrorTagBackward::TransitionTag()
+ {
+ CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
+ TCFMcpr::TReConnectComplete* msg = NULL;
+ if ( iContext.iMessage.IsMessage<TCFMcpr::TReConnectComplete>() )
+ {
+ msg = message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage);
+ }
+
+ if ( !msg )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TRetryConnectionOrProcessErrorTagBackward::TransitionTag() KProcessError",(TInt*)&iContext.Node());
+ return S60MCprStates::KProcessError | NetStateMachine::EBackward;
+ //return KErrorTag | NetStateMachine::EForward;
+ }
+ else// if ( node.ServiceProvider()->ProviderInfo().APId() == node.PolicyPrefs().IapId() )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TRetryConnectionOrProcessErrorTagBackward::TransitionTag() KRetryConnection",(TInt*)&iContext.Node());
+ return S60MCprStates::KRetryConnection | NetStateMachine::EForward;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // TNoTagOrProcessErrorBackwardTag::TransitionTag
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT(TNoTagOrProcessErrorBackwardTag, NetStateMachine::MStateFork, TContext)
+ TInt TNoTagOrProcessErrorBackwardTag::TransitionTag()
+ {
+ if ( iContext.iMessage.IsMessage<TEBase::TError>() )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrProcessErrorBackwardTag::TransitionTag() KProcessError",(TInt*)&iContext.Node());
+ return S60MCprStates::KProcessError | NetStateMachine::EBackward;
+ }
+ else
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TNoTagOrProcessErrorBackwardTag::TransitionTag() KNoTag",(TInt*)&iContext.Node());
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+ }
+
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::NewL
+ // -----------------------------------------------------------------------------
+ //
+ MeshMachine::CNodeActivityBase* CS60ConnectionRecoveryActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, // codescanner::leave
+ MeshMachine::AMMNodeBase& aNode )
+ {
+ return new (ELeave) CS60ConnectionRecoveryActivity( aActivitySig, aNode ); // codescanner::leave
+ }
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::CS60ConnectionRecoveryActivity
+ // -----------------------------------------------------------------------------
+ //
+ CS60ConnectionRecoveryActivity::CS60ConnectionRecoveryActivity( const MeshMachine::TNodeActivity& aActivitySig,
+ MeshMachine::AMMNodeBase& aNode )
+ : S60MCprStates::CS60ErrorRecoveryActivity( aActivitySig, aNode )
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::ReplyToOriginators
+ // -----------------------------------------------------------------------------
+ //
+ void CS60ConnectionRecoveryActivity::ReplyToOriginators( TEErrorRecovery::TErrorRecoveryResponse& aCFMessageSig )
+ {
+ NM_LOG_START_BLOCK(KESockMeshMachine, _L8("CS60ConnectionRecoveryActivity::ReplyToOriginators"));
+ NM_LOG((KESockMeshMachine, _L8("[this=0x%08x] "), this));
+ NM_LOG_MESSAGE(KESockMeshMachine, aCFMessageSig);
+ NM_LOG_END_BLOCK(KESockMeshMachine, _L8("CS60ConnectionRecoveryActivity::ReplyToOriginators"));
+ for ( TInt n = iOriginators.Count() - 1; n >= 0; n-- )
+ {
+ Messages::TNodePeerId& peerId = iOriginators[n];
+ TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(aCFMessageSig, peerId.RecipientId());
+ peerId.PostMessage( iNode.Id(), resp );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::TAwaitingReConnectComplete::Accept
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT( CS60ConnectionRecoveryActivity::TAwaitingReConnectComplete,
+ NetStateMachine::MState,
+ CS60ConnectionRecoveryActivity::TContext )
+ TBool CS60ConnectionRecoveryActivity::TAwaitingReConnectComplete::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
+ TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
+ if ( msg )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingReConnectComplete::TransitionTag() NOT Accept sending TErrorRecoveryResponse",(TInt*)&iContext.Node());
+ CS60ConnectionRecoveryActivity& ac = static_cast<CS60ConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TErrResponse propagateResp( TErrResponse::EPropagate,
+ ac.iOriginalErrContext.iStateChange.iError,
+ ac.iOriginalErrContext.iMessageId );
+ TEErrorRecovery::TErrorRecoveryResponse errResp( propagateResp );
+ ac.ReplyToOriginators( errResp );
+ ac.SetIdle();
+ iContext.iMessage.ClearMessageId();
+ return EFalse;
+ }
+ if ( iContext.iMessage.IsMessage<TCFMcpr::TReConnectComplete>() )
+ {
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingReConnectComplete::TransitionTag() Accept",(TInt*)&iContext.Node());
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::TTransitionBase::Error
+ // -----------------------------------------------------------------------------
+ //
+ void CS60ConnectionRecoveryActivity::TTransitionBase::Error( TInt /*aError*/ )
+ {
+ //Reply to the Error Activity and terminate
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
+ CS60ConnectionRecoveryActivity& ac = static_cast<CS60ConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse errResp( TErrResponse( TErrResponse::EPropagate,
+ ac.iOriginalErrContext.iStateChange.iError,
+ ac.iOriginalErrContext.iMessageId ));
+ ac.ReplyToOriginators( errResp );
+ S60MCPRLOGSTRING1("S60MCPR<%x>::TTransitionBase::Error()",(TInt*)&iContext.Node());
+ iContext.iNodeActivity->SetIdle();
+ }
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::TStoreErrorContext::DoL
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT( CS60ConnectionRecoveryActivity::TStoreErrorContext,
+ NetStateMachine::MStateTransition,
+ CS60ConnectionRecoveryActivity::TContext )
+ void CS60ConnectionRecoveryActivity::TStoreErrorContext::DoL() // codescanner::leave
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
+ CS60ConnectionRecoveryActivity& activity = static_cast<CS60ConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ activity.iOriginalErrContext = message_cast<TEErrorRecovery::TErrorRecoveryRequest>(iContext.iMessage).iErrContext;
+ }
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::TSendRetryRecoveryResponse::DoL
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT( CS60ConnectionRecoveryActivity::TSendRetryRecoveryResponse,
+ NetStateMachine::MStateTransition,
+ CS60ConnectionRecoveryActivity::TContext )
+ void CS60ConnectionRecoveryActivity::TSendRetryRecoveryResponse::DoL() // codescanner::leave
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
+ CS60ConnectionRecoveryActivity& activity = static_cast<CS60ConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse err( TErrResponse( TErrResponse::ERetry,
+ KErrNone,
+ activity.iOriginalErrContext.iMessageId ) );
+ S60MCPRLOGSTRING2("S60MCPR<%x>::TSendRetryRecoveryResponse<%x>::DoL()",(TInt*)&iContext.Node(),(TInt*)this);
+ // We must clear out the activity error to prevent last automatic error message from the node.
+ iContext.iNodeActivity->SetError( KErrNone );
+ activity.ReplyToOriginators( err );
+ }
+
+
+ // -----------------------------------------------------------------------------
+ // CS60ConnectionRecoveryActivity::TSendPropagateRecoveryResponse::DoL
+ // -----------------------------------------------------------------------------
+ //
+ DEFINE_SMELEMENT( CS60ConnectionRecoveryActivity::TSendPropagateRecoveryResponse,
+ NetStateMachine::MStateTransition,
+ CS60ConnectionRecoveryActivity::TContext )
+ void CS60ConnectionRecoveryActivity::TSendPropagateRecoveryResponse::DoL() // codescanner::leave
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
+ CS60ConnectionRecoveryActivity& activity =
+ static_cast<CS60ConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ // Override original error with activity error.
+ TEErrorRecovery::TErrorRecoveryResponse err( TErrResponse( TErrResponse::EPropagate,
+ activity.Error(),
+ activity.iOriginalErrContext.iMessageId ) );
+ S60MCPRLOGSTRING2("S60MCPR<%x>::TSendPropagateRecoveryResponse::DoL() %d",(TInt*)&iContext.Node(),(TInt)activity.Error());
+ // We must clear out the activity error to prevent last automatic error message from the node.
+ iContext.iNodeActivity->SetError( KErrNone );
+ activity.ReplyToOriginators( err );
+ }
+
+ } // namespace S60MCprErrorRecoveryActivity
+
+// End of File