bearermanagement/S60MCPR/src/s60mcprerrorrecoveryactivity.cpp
changeset 0 5a93021fdf25
child 1 40cb640ef159
--- /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