sipvoipprovider/svptransfer/src/svptransferstatecontext.cpp
changeset 0 a4daefaec16c
child 16 6134b5029079
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sipvoipprovider/svptransfer/src/svptransferstatecontext.cpp	Mon Jan 18 20:12:36 2010 +0200
@@ -0,0 +1,1434 @@
+/*
+* Copyright (c) 2006 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:  Transfer state context class for state machine
+*
+*/
+
+#include <mcetransactiondatacontainer.h> // TMceTransactionDataContainer 
+#include <mceoutrefer.h>                 // CMceRefer, CMceOutRefer
+#include <mceoutevent.h>                 // CMceEvent
+#include <escapeutils.h>
+#include <mcesession.h>
+#include <crcseprofileentry.h>
+#include <crcseprofileregistry.h>
+
+#include "svpsessionbase.h"
+#include "svptransferstatecontext.h"
+#include "svptransferstatebase.h"
+#include "svptransferidlestate.h"
+#include "svptransferpendingstate.h"
+#include "svptransferacceptedstate.h"
+#include "svptransferterminatingstate.h"
+#include "svptransferterminatedstate.h" 
+#include "svptransferobserver.h"
+#include "svplogger.h"          
+#include "svpuriparser.h"
+#include "svpconsts.h"
+#include "svpholdcontext.h"
+#include "svpholdcontroller.h"
+#include "svpcleanupresetanddestroy.h"
+
+
+// ---------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CSVPTransferStateContext::CSVPTransferStateContext( 
+                                CMceSession* aMceSession,                                
+                                CSVPSessionBase* aSVPSession,                                
+                                TMceTransactionDataContainer& aContainer, 
+                                MSVPTransferObserver& aObserver ) :
+        iMceSession( aMceSession ),
+        iSVPSession( aSVPSession ),        
+        iTargetSession( NULL ),
+        iContainer( aContainer ),
+        iTransferObserver( aObserver ),
+        iStates( NULL ),
+        iCurrentState( NULL ),
+        iMceRefer( NULL ),        
+        iMceEvent( NULL ),
+        iAttended( EFalse ),
+        iIncomingReferTo ( NULL ),
+        iIncomingReferredBy ( NULL ),
+        iIncomingReplaces (NULL)
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ConstructL() 
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::ConstructL In" )
+    
+    // Create the transfer states in the state array.
+    InitializeStateArrayL();  
+           
+    // Initialize idle state to current state. Note, that it is not
+    // applied yet.
+    SetCurrentStateL( KSVPTransferIdleStateIndex );
+    
+    SVPDEBUG1( "CSVPTransferStateContext::ConstructL Out" )
+    }
+
+// -----------------------------------------------------------------------------
+// CSVPTransferStateContext::NewL
+// -----------------------------------------------------------------------------
+CSVPTransferStateContext* CSVPTransferStateContext::NewL( 
+                                CMceSession* aMceSession,
+                                CSVPSessionBase* aSVPSession,
+                                TMceTransactionDataContainer& aContainer, 
+                                MSVPTransferObserver& aObserver )
+    {    
+    CSVPTransferStateContext* self = new ( ELeave ) CSVPTransferStateContext(
+                                                        aMceSession,
+                                                        aSVPSession,
+                                                        aContainer, 
+                                                        aObserver );
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::~CSVPTransferStateContext
+// ---------------------------------------------------------------------------
+//
+CSVPTransferStateContext::~CSVPTransferStateContext()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::~CSVPTransferStateContext In" )
+    
+    if ( iStates )
+        {
+        iStates->ResetAndDestroy();
+        iStates->Close();
+        delete iStates;
+        }
+    
+    delete iMceEvent;
+    delete iMceRefer;
+    delete iIncomingReferTo;
+    delete iIncomingReferredBy;
+    delete iIncomingReplaces;
+    
+    SVPDEBUG1( "CSVPTransferStateContext::~CSVPTransferStateContext Out" )        
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetCurrentStateL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetCurrentStateL(
+        TSVPTransferStateIndex aStateIndex )
+    {
+    // Check, if the transition is valid
+    if ( !IsStateTransitionAccepted( aStateIndex ) )
+        {
+        SVPDEBUG2( "CSVPTransferStateContext::SetCurrentStateL: STATE ERROR stateindex: %i", aStateIndex )
+        User::Leave( KSVPErrTransferStateError );
+        }
+    else
+        {
+        iCurrentState = ( *iStates )[ aStateIndex ];
+        iCurrentState->Enter( *this );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CurrentState
+// ---------------------------------------------------------------------------
+//
+TSVPTransferStateIndex CSVPTransferStateContext::CurrentState() const
+    {
+    return iStates->Find( iCurrentState );    
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ApplyCurrentStateL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ApplyCurrentStateL()
+   {
+   iCurrentState->ApplyL( *this );
+   }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::TransferObserver
+// ---------------------------------------------------------------------------
+//
+MSVPTransferObserver& CSVPTransferStateContext::TransferObserver()
+    {
+    return iTransferObserver;    
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetMceSessionObject
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetMceSessionObject( CMceSession* aSession )
+    {
+    iMceSession = aSession;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::MceSessionObject
+// ---------------------------------------------------------------------------
+//
+CMceSession* CSVPTransferStateContext::MceSessionObject()
+    {
+    return iMceSession;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetMceRefer
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetMceRefer( CMceRefer* aRefer )
+    {
+    if ( iMceRefer != aRefer )
+        {
+        delete iMceRefer;
+        iMceRefer = aRefer;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::MceRefer
+// ---------------------------------------------------------------------------
+//
+CMceRefer* CSVPTransferStateContext::MceRefer()
+    {
+    return iMceRefer;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetAttended
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetAttended( const TBool aAttended )
+    {
+    iAttended = aAttended;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::IsAttended
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferStateContext::IsAttended()
+    {
+    return iAttended;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckIsSessionRemoteHold
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferStateContext::CheckIsSessionRemoteHold()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckIsSessionRemoteHold In" )
+    
+    TBool ret = EFalse;
+    
+    if ( iSVPSession->HasHoldController() &&
+         MCCPCallObserver::ECCPStateDisconnecting != iSVPSession->State() )
+        {
+        SVPDEBUG1("CSVPTransferStateContext::CheckIsSessionRemoteHold, Check hold state" )
+        
+        if ( ESVPOnHold == iSVPSession->HoldController().HoldState() &&
+             ESVPRemoteHold == iSVPSession->HoldController().HoldRequest() )
+            {
+            // Session is remote holded -> Snom/EyeBeam as unattended transferer case.
+            SVPDEBUG1( "CSVPTransferStateContext:CheckIsSessionRemoteHold, transferer is Snom, EyeBeam or similar" )
+            ret = ETrue;
+            }
+        }
+    
+    SVPDEBUG2("CSVPTransferStateContext::CheckIsSessionRemoteHold Out return: %d",ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetTransferDataL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetTransferDataL(
+        CDesC8Array* aUserAgentHeaders, TInt aSecureStatus )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL In" )
+    
+    if ( aUserAgentHeaders )
+        {
+        if ( iIncomingReplaces && IsAttended() )
+            {
+            SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL: add replaces header" )
+            TBuf8<KSVPTempStringlength> replacesString;
+            replacesString.Append( KSVPReplacesColonTxt );
+            // add IncomingReplaces
+            replacesString.Append( IncomingReplaces() );
+            // Finally add collected Replaces string to header
+            aUserAgentHeaders->AppendL( replacesString );
+            }
+        
+        if ( iIncomingReferredBy )
+            {
+            SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL: Add referredBy header" )
+            TBuf8<KSVPTempStringlength> referredByString;
+            referredByString.Append( KSVPReferredBy );
+            // add IncomingReferredBy
+            referredByString.Append( IncomingReferredBy() );
+            // Finally add collected Referred-By string to header
+            aUserAgentHeaders->AppendL( referredByString );
+            }
+        }
+    
+    // Update transfer target address according preferred securesetting.
+    UpdateTransferTargetL( aSecureStatus );
+    
+    SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::IsIncoming
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferStateContext::IsIncoming()
+    {
+    return ( NULL != iIncomingReferTo );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetIncomingReferToL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetIncomingReferToL( const TDesC8& aReferTo )
+    {
+    SVPDEBUG1("CSVPTransferStateContext::SetIncomingReferToL In" )
+    
+    ResetIncomingReferTo();
+    
+    // modify aReferTo
+    HBufC8* referTo = CompleteReferToL( aReferTo );
+    CleanupStack::PushL( referTo );
+
+    // at this point referto must contains legal sip uri
+    RemoveExtraParameters( referTo );
+    
+    // Check length - moSession construct limitation
+    // sip: or sips: prefix will be added later, so 95 is maximum
+    if ( referTo->Length() < ( KSVPMaxUriLength - KSVPSipPrefixLength ) )
+        {
+        // Copy and convert the "refer to" -parameter.
+        iIncomingReferTo = HBufC::NewL( referTo->Length() );
+        TPtr temp = iIncomingReferTo->Des();
+        temp.Copy( *referTo );
+        }
+    else
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL: referTo too long, Leave" )
+        User::Leave( KErrArgument );
+        }
+    
+    CleanupStack::PopAndDestroy( referTo );
+    
+   SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferToL lenght: %d",
+            iIncomingReferTo->Length())
+    SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL Out" )
+    }
+
+// -----------------------------------------------------------------------------
+// CSVPSessionBase::SetIncomingReferredByL
+// -----------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetIncomingReferredByL( const TDesC8& aReferredBy )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL In" )
+    
+    ResetIncomingReferredBy();
+    
+    // modify aReferredBy
+    HBufC8* referredBy = CompleteReferredByL( aReferredBy );
+    CleanupStack::PushL( referredBy );
+    
+    // Copy and convert the "Referred By" -parameter.    
+    iIncomingReferredBy = HBufC::NewL( referredBy->Length() );
+    TPtr temp = iIncomingReferredBy->Des();
+    temp.Copy( *referredBy );
+    CleanupStack::PopAndDestroy( referredBy );
+    
+    SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferredByL lenght: %d",
+            iIncomingReferredBy->Length() )
+    SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL Out" )
+    }    
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetIncomingReplacesL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetIncomingReplacesL( const TDesC8& aString )
+    { 
+    SVPDEBUG1("CSVPTransferStateContext::SetIncomingReplacesL In" )
+    
+    ResetIncomingReplaces();
+    
+    // modify Replaces
+    HBufC8* string = CompleteReplacesL( aString );
+    CleanupStack::PushL( string );
+    
+    // Copy and convert the "Replaces" -parameter.    
+    iIncomingReplaces = HBufC::NewL( string->Length() );
+    TPtr temp = iIncomingReplaces->Des();
+    temp.Copy( *string );
+    CleanupStack::PopAndDestroy( string );
+    
+    SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReplacesL lenght: %d",
+            iIncomingReplaces->Length() )
+    SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReplacesL Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CompleteReplacesL
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSVPTransferStateContext::CompleteReplacesL( const TDesC8& aString )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL In" )
+    
+    // Copy the parameter to a new buffer.
+    HBufC8* string = aString.AllocLC();
+    // If "?Replaces=" found attended transfer case
+    TInt position = CheckReplacesTxt( *string );
+    SVPDEBUG2( "    CheckReplacesTxt returns = %d", position );
+    
+    if ( KErrNotFound != position )
+        {
+        TakeReplacesTxt( string, position );
+        CleanupStack::Pop( 1 ); // string, ReAlloc possible
+        CleanupStack::PushL( string );
+        }
+    
+    // Check ">" and remove text after it if exists
+    position = CheckRightBracket( *string );
+    SVPDEBUG2("    CheckRightBracket returns = %d" , position )
+    
+    if ( KErrNotFound != position )
+        {
+        // ">" found
+        CutStringFromPosition( string, position );
+        CleanupStack::Pop( 1 ); // string, ReAlloc possible
+        CleanupStack::PushL( string );
+        }
+    
+    HBufC8* temp = EscapeUtils::EscapeDecodeL( *string );
+    CleanupStack::PopAndDestroy( string );
+    
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL Out" )
+    return temp;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CompleteReferToL
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSVPTransferStateContext::CompleteReferToL( const TDesC8& aUri )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL In" )
+    
+    // Copy the parameter to a new buffer.
+    HBufC8* uri = aUri.AllocLC();
+    
+    // Check "<" and remove it and text before it if exists
+    TInt position = CheckLeftBracket( *uri );
+    
+    if ( KErrNotFound != position )
+        {
+        RemoveLeftBracket( uri, position );
+        CleanupStack::Pop( 1 ); // uri, ReAlloc possible
+        CleanupStack::PushL( uri );
+        }
+    
+    // Check ";user=phone" and remove if exists
+    position = CheckUserEqualsPhone( *uri );
+    
+    if ( KErrNotFound != position )
+        {
+        // ";user=phone" found
+        RemoveUserEqualsPhone( uri, position );
+        CleanupStack::Pop( 1 ); // uri, ReAlloc possible
+        CleanupStack::PushL( uri );
+        }
+    
+    // Check ">" and remove text after it if exists
+    position = CheckRightBracket( *uri );
+    
+    if ( KErrNotFound != position )
+        {
+        // ">" found
+        CutStringFromPosition( uri, position );
+        CleanupStack::Pop( 1 ); // uri, ReAlloc possible
+        CleanupStack::PushL( uri );
+        }
+    
+    // Check "KSVPQuesReplacesTxt" and remove text after it if exists
+    // If it is found -> attended transfer case
+    position = CheckReplacesTxt( *uri );
+    
+    if ( KErrNotFound != position )
+        {
+        // Found -> attended case.
+        SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= found -> attended transfer" )
+        SetAttended( ETrue );
+        SetIncomingReplacesL( aUri );
+        CutStringFromPosition( uri, position );
+        }
+    else
+        {
+        // Not found -> unattended case.
+        SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= not found -> unattended transfer" )
+        SetAttended( EFalse );
+        }
+
+    // Check "?X-Sipx-Authidentity=" and remove text after it if exists
+    position = CheckAuthidentity( *uri );
+
+    if ( KErrNotFound != position )
+        {
+        // "?X-Sipx-Authidentity=" found
+        CutStringFromPosition( uri, position );
+        CleanupStack::Pop( 1 ); // uri, ReAlloc possible
+        CleanupStack::PushL( uri );
+        }
+
+    // Check "sip:" and remove it if exists
+    if ( KErrNone == uri->Find( KSVPSipPrefix ) )
+        {
+        // sip: is in the beginning of the string
+        SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sip:" )
+        uri->Des().Delete( 0, KSVPSipPrefixLength );
+        }
+
+    // Check "sips:" and remove it if exists
+    if ( KErrNone == uri->Find( KSVPSipsPrefix ) )
+        {
+        // sips: is in the beginning of the string
+        SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sips:" )
+        uri->Des().Delete( 0, KSVPSipsPrefixLength );
+        }
+
+    // Check ":" and remove text after it if exists,
+    // some server might add this after transfer target address
+    position = uri->Find( KSVPCln );
+
+    if ( KErrNotFound != position )
+        {
+        // ":" found
+        SVPDEBUG2( "CSVPTransferStateContext::CompleteReferToL remove text after %d ", position )
+        uri->Des().Delete( position, uri->Length() - position );
+        }
+
+    CleanupStack::Pop( 1 ); // uri, ReAlloc possible
+    
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL Out" )
+    return uri;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CompleteReferredByL
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSVPTransferStateContext::CompleteReferredByL(
+        const TDesC8& aReferredBy )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL In" )
+    
+    // Copy the parameter to a new buffer.
+    HBufC8* referredBy = aReferredBy.AllocLC();
+    
+    // Check "Referred-By:" and remove it
+    TInt position = CheckReferredByTxt( *referredBy );
+    
+    if ( KErrNotFound != position )
+        {
+        // "Referred-By:" found.
+        RemoveReferredByTxt( referredBy, position );
+        }
+    
+    CleanupStack::Pop( 1 ); // referredBy, ReAlloc possible
+    
+    SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL Out" )
+    return referredBy;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckUserEqualsPhone
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckUserEqualsPhone( const TDesC8& aUri ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckUserEqualsPhone" )
+    
+    return ( aUri.FindF( KSVPUserEqualsPhone ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::RemoveUserEqualsPhone
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::RemoveUserEqualsPhone(
+        HBufC8*& aUri, TInt aPosition ) const
+    {
+    SVPDEBUG2( "CSVPTransferStateContext::RemoveUserEqualsPhone posit = %d", aPosition )
+    
+    aUri->Des().Delete( aPosition, KSVPUserEqualsPhoneLenght );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::RemoveExtraParameters
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::RemoveExtraParameters( HBufC8*& aUri ) const 
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters In" )
+    
+    // remove all extra parameters from given address
+    TInt index = aUri->Locate( KSVPSemiColonMark );
+    TInt bracketLocation = KErrNotFound;
+    
+    SVPDEBUG3( "CSVPTransferStateContext::RemoveExtraParameters index = %d, length = %d",
+        index, aUri->Length() )
+    
+    if ( KErrNotFound != index )
+        {
+        // Delete ";" and text after it
+        aUri->Des().Delete( index, aUri->Length() );
+        }
+    
+    // Check "<" and remove it and text before it if exists
+    bracketLocation = CheckLeftBracket( *aUri );
+    
+    if ( KErrNotFound != bracketLocation )
+        {
+        RemoveLeftBracket( aUri, bracketLocation );
+        }
+    
+    // Check ">" and remove text after it if exists
+    bracketLocation = CheckRightBracket( *aUri );
+    
+    if ( KErrNotFound != bracketLocation )
+        {
+        CutStringFromPosition( aUri, bracketLocation );
+        }
+    
+    SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckReplacesTxt
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckReplacesTxt( const TDesC8& aUri ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckReplacesTxt" )
+    
+    return ( aUri.FindF( KSVPQuesReplacesTxt ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CutStringFromPosition
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::CutStringFromPosition(
+        HBufC8*& aUri, TInt aPosition ) const
+    {
+    SVPDEBUG2( "CSVPTransferStateContext::CutStringFromPosition posit = %d", aPosition )
+    aUri->Des().Delete( aPosition, aUri->Length() - aPosition );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckReferredByTxt
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckReferredByTxt(
+        const TDesC8& aReferredBy ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckReferredByTxt" )
+    
+    return ( aReferredBy.FindF( KSVPReferredBy ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::RemoveReferredByTxt
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::RemoveReferredByTxt(
+        HBufC8*& aReferredBy, TInt aPosition ) const
+    {
+    SVPDEBUG2( "CSVPTransferStateContext::RemoveReferredByTxt posit = %d", aPosition )
+    
+    aReferredBy->Des().Delete( aPosition, KSVPReferredByLength + 1 );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::TakeReplacesTxt
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::TakeReplacesTxt(
+        HBufC8*& aString, TInt aPosition ) const
+    {
+    SVPDEBUG2( "CSVPTransferStateContext::TakeReplacesTxt posit = %d", aPosition )
+    
+    aString->Des().Delete( 0, aPosition + KSVPQuesReplacesTxtLength );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckLeftBracket
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckLeftBracket( const TDesC8& aUri ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckLeftBracket" )
+    
+    // Return position of "<" or KErrNotFound
+    return ( aUri.Find( KSVPLeftBracketMark ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::RemoveLeftBracket
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::RemoveLeftBracket(
+        HBufC8*& aUri, TInt aPosition ) const
+    {
+    SVPDEBUG2( "CSVPTransferStateContext::RemoveLeftBracket posit = %d", aPosition )
+    
+    aUri->Des().Delete( 0, aPosition + KSVPSingleBracketLength );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckRightBracket
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckRightBracket( const TDesC8& aUri ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckRightBracket" )
+    
+    return ( aUri.Find( KSVPRightBracketMark ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CheckAuthidentity  
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferStateContext::CheckAuthidentity( const TDesC8& aUri ) const
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::CheckAuthidentity" )
+    return ( aUri.Find( KSVPAuthidentity ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::IncomingReferTo
+// ---------------------------------------------------------------------------
+//
+const TDesC& CSVPTransferStateContext::IncomingReferTo()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::IncomingReferTo" )
+    
+    return *iIncomingReferTo;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::UpdateTransferTargetL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::UpdateTransferTargetL( TInt aSecureStatus )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL In" )
+    
+    if ( iIncomingReferTo )
+        {
+        if ( KSVPStatusNonSecure == aSecureStatus )
+            {
+            SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIP uri" )
+            
+            // Check "sips:" and remove it if exists
+            if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
+                {
+                // sips: is in the beginning of the string, position 0
+                SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sips:" )
+                iIncomingReferTo->Des().Delete( 0, KSVPSipsPrefixLength );
+                }
+            
+            // Add "sip:" prefix in the beginning of the string, if it's missing.
+            if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
+                {
+                SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sip:" )
+                iIncomingReferTo = iIncomingReferTo->ReAllocL(
+                        iIncomingReferTo->Length() + KSVPSipPrefixLength );
+                iIncomingReferTo->Des().Insert( 0, KSVPSipPrefix2 );
+                }
+            }
+        else
+            {
+            SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIPS" )
+            
+            // Check "sip:" and remove it if exists
+            if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
+                {
+                // sip: is in the beginning of the string
+                SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sip:" )
+                iIncomingReferTo->Des().Delete( 0, KSVPSipPrefixLength );
+                }
+            
+            // Add "sips:" prefix in the beginning of the string, if it's missing.
+            if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
+                {
+                SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sips:" )
+                iIncomingReferTo = iIncomingReferTo->ReAllocL(
+                        iIncomingReferTo->Length() + KSVPSipsPrefixLength );
+                iIncomingReferTo->Des().Insert( 0, KSVPSipsPrefix2 );
+                }
+            }
+        }
+    else
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL IncomingReferTo Not OK" )
+        }
+    
+    SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ResetIncomingReferTo
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ResetIncomingReferTo()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferTo" )    
+    
+    if ( iIncomingReferTo )
+        {
+        delete iIncomingReferTo;
+        iIncomingReferTo = NULL;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ResetIncomingReferredBy
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ResetIncomingReferredBy()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferredBy" )
+    
+    if ( iIncomingReferredBy )
+        {
+        delete iIncomingReferredBy;
+        iIncomingReferredBy = NULL;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::IncomingReferredBy
+// ---------------------------------------------------------------------------
+//
+const TDesC& CSVPTransferStateContext::IncomingReferredBy()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::IncomingReferredBy" )
+    
+    return *iIncomingReferredBy;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::IncomingReplaces
+// ---------------------------------------------------------------------------
+//
+const TDesC& CSVPTransferStateContext::IncomingReplaces()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::IncomingReplaces" )
+    
+    return *iIncomingReplaces;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ResetIncomingReplaces
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ResetIncomingReplaces()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReplaces" )
+    
+    if ( iIncomingReplaces )
+        {
+        delete iIncomingReplaces;
+        iIncomingReplaces = NULL;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetTransferParmsL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetTransferParmsL(
+        CSVPSessionBase* aTargetSession, const TDesC& aTarget,
+        const TBool aAttendedTransfer )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL In" )
+    
+    // No target session as default. 
+    iTargetSession = NULL;
+    
+    // Delete possible old refer 
+    delete iMceRefer;
+    iMceRefer = NULL;
+    
+    // Set attended/unattended transfer
+    SetAttended( aAttendedTransfer );
+    
+    // Create mce out refer using given target parameter or call
+    if ( aTarget.Length() > 0 )
+        {
+        CreateMceOutReferL( aTarget );
+        }
+    else
+        {
+        CreateMceOutReferL( aTargetSession );
+        }
+    
+    SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CreateMceOutReferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::CreateMceOutReferL( const TDesC& aTarget )
+    {
+    // Create mce out refer using target string (unattended).   
+    SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) In" )
+    
+    // Copy 'refer to' argument
+    HBufC8* target = HBufC8::NewLC( aTarget.Length() );
+    target->Des().Copy( aTarget );
+    
+    // Parse target with uri parser, use session recipient as domain source 
+    CSVPUriParser* uriParser = CSVPUriParser::NewLC();
+    HBufC8* referto = NULL;
+    RPointerArray< CRCSEProfileEntry > entryArray;
+    CleanupResetAndDestroy< RPointerArray<CRCSEProfileEntry> >::PushL( entryArray );
+    CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC();
+    
+    // Get VoIP profile by service id
+    reg->FindByServiceIdL( iSVPSession->Parameters().ServiceId(), entryArray );
+    __ASSERT_ALWAYS( entryArray.Count(), User::Leave( KErrArgument ) );
+    CRCSEProfileEntry* entry = entryArray[0];
+    uriParser->SetUserEqualsPhoneRequiredL(
+            CRCSEProfileEntry::EOn == entry->iUserPhoneUriParameter );
+    
+    CleanupStack::PopAndDestroy( reg );
+    CleanupStack::PopAndDestroy( &entryArray );
+
+    HBufC8* recipient = NULL;
+    const CMceSession& session = iSVPSession->Session();
+    __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
+
+    if ( iSVPSession->IsMobileOriginated() ) 
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), MO case" )
+        const TDesC8& recip = session.Recipient();
+        __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
+        recipient = HBufC8::NewLC( recip.Length() );
+        recipient->Des().Copy( recip );
+        }
+    else
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), MT case" )
+        const TDesC8& orig = session.Originator();
+        __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
+        recipient = HBufC8::NewLC( orig.Length() );
+        recipient->Des().Copy( orig );    
+        }
+
+    // remove all extra parameters from recipient address
+    RemoveExtraParameters( recipient );
+    
+    SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) recipient->Length() = %d",
+               recipient->Length() )
+    
+    if ( iSVPSession->SecureMandatory() || iSVPSession->SecurePreferred() )
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIPS URI..." )
+        referto = uriParser->CompleteSecureSipUriL( *target, *recipient );
+        }
+    else
+        {
+        SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIP URI..." )
+        referto = uriParser->CompleteSipUriL( *target, *recipient );
+        }
+    
+    CleanupStack::PushL( referto );
+    
+    SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 1 referto->Length() = %d",
+               referto->Length() )
+    
+    // remove all extra parameters from referto
+    RemoveExtraParameters( referto );
+
+    SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 2 referto->Length() = %d",
+               referto->Length() )
+    
+    // Create the refer
+    delete iMceRefer;
+    iMceRefer = NULL;
+    iMceRefer = CMceOutRefer::NewL( *iMceSession, *referto, CMceRefer::ENoSuppression );
+    CleanupStack::PopAndDestroy( referto );
+    
+    CleanupStack::PopAndDestroy( recipient );
+    CleanupStack::PopAndDestroy( uriParser );
+    CleanupStack::PopAndDestroy( target );
+    
+    SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) Out" )
+	}
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::CreateMceOutReferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::CreateMceOutReferL( CSVPSessionBase* aTargetSession )
+    {
+    // Create mce out refer using session (attended).   
+    SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) In" )    
+    
+    // Store target session 
+    iTargetSession = aTargetSession;
+    
+    // Construct the refer-to string
+    HBufC8* referto = HBufC8::NewLC( KSVPTempStringlength );
+    TPtr8 refptr = referto->Des();
+    
+    if ( iTargetSession )
+        {
+        // Set refer-to for the attended transfer using the target session,
+        // that can not be the same as the owner session of the 
+        // transfer controller.
+        if ( iSVPSession != iTargetSession )
+            {
+            SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) TargetSession = 0x%x", &iTargetSession )
+            
+            HBufC8* recipient = NULL;
+            const CMceSession& session = iTargetSession->Session();
+            __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
+            
+            if ( iTargetSession->IsMobileOriginated() ) 
+                {
+                const TDesC8& recip = session.Recipient();
+                __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
+                recipient = HBufC8::NewLC( recip.Length() );
+                recipient->Des().Copy( recip );
+                }
+            else
+                {
+                const TDesC8& orig = session.Originator();
+                __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
+                recipient = HBufC8::NewLC( orig.Length() );
+                recipient->Des().Copy( orig );    
+                }
+            
+            // remove all extra parameters from recipient address
+            RemoveExtraParameters( recipient );
+            
+            SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) recipient->Length() = %d",
+               recipient->Length() )
+            
+            // Set the refer-to address (recipient)
+            refptr.Append( recipient->Des() );
+            CleanupStack::PopAndDestroy( recipient );
+            
+            // Gather up the rest of the refer-to data (replaces etc.)  
+            // from the target session (sessionbase) member variables.
+            TBuf8<KSVPTempStringlength> tmp( KNullDesC8 );
+            tmp.Append( KSVPQuesReplacesTxt ); // Set CallId
+            
+            if ( iTargetSession->CallId() )
+                {
+                // Set "replaces" callid string starting from next char 
+                // the of KSVPCallId_replaces -text
+                TDesC8* callid = iTargetSession->CallId();
+                TInt index = callid->Find( KSVPCallId_replaces );
+                
+                if ( KErrNotFound != index )
+                    {
+                    // Check and encode the possible @ char of the callid 
+                    // to "%40" format. This kind of callid e.g. in Cisco 7960.
+                    TInt index2 = callid->Find( KSVPAt );
+                    
+                    if ( KErrNotFound != index2 )
+                	    {
+                	    HBufC8* tmpCallId = HBufC8::NewLC( callid->Length() );
+                	    tmpCallId->Des().Append( callid->Mid( index +
+                	            KSVPCallId_replaces().Length() ) );
+                	    CSVPUriParser::EscapeEncodeSipUriL( tmpCallId,
+                                EscapeUtils::EEscapeUrlEncoded );
+                        tmp.Append( *tmpCallId );
+                        CleanupStack::Pop( 1 ); // tmpCallId, ReAlloc possible
+                        delete tmpCallId;
+                        }
+                    else
+                        {
+                        // Normal copy from the correct position
+                        tmp.Append( callid->Mid( index +
+                                KSVPCallId_replaces().Length() ) );
+                        }
+                    }
+                }
+            else
+                {
+                SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing CallId %i", KSVPErrTransferReferTo )
+                User::Leave( KSVPErrTransferReferTo );
+                }
+            
+            // To-header                    
+            if ( iTargetSession->ToHeader() )
+                {
+                tmp.Append( KSVPTo_tag );
+                
+                // Set "to" tag string starting from next char 
+                // of the KSVPTo_tag_replaces -text
+                TDesC8* toHdr = iTargetSession->ToHeader();
+                TInt index = toHdr->Find( KSVP_tag );
+                SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) toHdr index = %d", index )
+                
+                if ( KErrNotFound != index )
+                    {
+                    tmp.Append( toHdr->Mid( index + KSVPTagLength ) );
+                    }
+                }
+            else
+                {
+                SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing ToHeader %i", KSVPErrTransferReferTo )        
+                User::Leave( KSVPErrTransferReferTo );
+                }
+            
+            // From-header
+            if ( iTargetSession->FromHeader() )
+                {                    
+                tmp.Append( KSVPFrom_tag );                    
+                
+                // Set "from" tag string starting from next char of 
+                // the KSVPTo_tag_replaces -text
+                TDesC8* fromHdr = iTargetSession->FromHeader();
+                TInt index = fromHdr->Find( KSVP_tag );
+                SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) fromHdr index = %d", index )
+                
+                if ( KErrNotFound != index )
+                    {
+                    tmp.Append( fromHdr->Mid( index + KSVPTagLength ) );
+                    }
+                }
+            else
+                {
+                SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing FromHeader %i", KSVPErrTransferReferTo )
+                User::Leave( KSVPErrTransferReferTo );
+                }
+            
+            refptr.Append( tmp );
+            } // if ( iSVPSession != iTargetSession )
+        else
+            {
+            SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - the same target session %i", KSVPErrTransferReferTo )
+            User::Leave( KSVPErrTransferReferTo );
+            }
+        
+        // Create the refer
+        iMceRefer = CMceOutRefer::NewL( *iMceSession,
+                *referto, CMceRefer::ENoSuppression );
+        } // if (iTargetSession)
+    else
+        {
+        SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - no target session %i", KSVPErrTransferReferTo )        
+        User::Leave( KSVPErrTransferReferTo );
+        }
+    
+    CleanupStack::PopAndDestroy( referto );    	
+    
+    SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) Out" )        
+	}
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::ExecuteReferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::ExecuteReferL()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL In" )
+    
+    delete iMceEvent;
+    iMceEvent = NULL;
+    
+    // Create headers for refer call.
+    CDesC8Array* headers = SetupHeadersL();
+    CleanupStack::PushL( headers );
+    
+    // Refer with headers, passes ownership.
+    iMceEvent = static_cast< CMceOutRefer* >(MceRefer())->ReferL( headers );          
+    CleanupStack::Pop( headers );
+    
+    // Execution of the refer. Pass ownership of the arguments. Generates 
+    // event to the MMceReferObserver. New MceOutEvent is created and events 
+    // of that then through MMceEventObserver interface.
+    iSVPSession->StartTimerL( KSVPReferExpirationTime,
+            KSVPReferTimerExpired  );// Start refer timer
+    
+    SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL Out" )
+	}
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetMceEvent
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::SetMceEvent( CMceEvent* aEvent )
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent In" )
+    
+    if ( iMceEvent != aEvent )
+        {
+        delete iMceEvent;
+        iMceEvent = aEvent;
+        SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Updated" )
+        }
+    
+    SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Out" )
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::MceEvent
+// ---------------------------------------------------------------------------
+//
+CMceEvent* CSVPTransferStateContext::MceEvent()
+    {
+    return iMceEvent;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::StopReferTimer
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::StopReferTimer()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::StopReferTimer" )
+    
+    iSVPSession->StopTimer( KSVPReferTimerExpired );
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::SetupHeadersL
+// ---------------------------------------------------------------------------
+//
+CDesC8Array* CSVPTransferStateContext::SetupHeadersL()
+    {
+    SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL In" )
+    
+    CDesC8ArrayFlat* headers = new( ELeave ) CDesC8ArrayFlat(
+            KSVPHeaderArrayGranularity );
+    CleanupStack::PushL( headers );
+    
+    // Set "referred by" value - that is this end of the session.
+    TBuf8<KSVPTempStringlength> tempRefBy;
+    tempRefBy.Append( KSVPReferredBy );
+    
+    if ( iSVPSession->IsMobileOriginated() )
+        {
+        TDesC8* fromHdr = iSVPSession->FromHeader();
+        if ( fromHdr )
+            {
+            TInt indexLeft = fromHdr->Find( KSVPLeftBracketMark );
+            TInt indexRight = fromHdr->Find( KSVPRightBracketMark );
+            SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight );
+
+            tempRefBy.Append( fromHdr->Mid( indexLeft,
+                    indexRight - indexLeft + KSVPSingleBracketLength ) );
+            }
+        }
+    else
+        {
+        TDesC8* toHdr = iSVPSession->ToHeader();
+        if ( toHdr )
+            {
+            TInt indexLeft = toHdr->Find( KSVPLeftBracketMark );
+            TInt indexRight = toHdr->Find( KSVPRightBracketMark );
+            SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight )
+
+            tempRefBy.Append( toHdr->Mid( indexLeft,
+                    indexRight - indexLeft + KSVPSingleBracketLength ) );
+            }
+        }
+    
+    headers->AppendL( tempRefBy );
+    CleanupStack::Pop( headers );
+    
+    SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL Out" )
+    return headers;
+    }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferStateContext::InitializeStateArrayL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferStateContext::InitializeStateArrayL()
+    {
+    // Create the array of the transfer states.
+    iStates = new ( ELeave ) RPointerArray<CSVPTransferStateBase>
+            ( KSVPTransferStateArraySize );
+    
+    // Transfer state classes are created here:
+    // Idle state
+    CSVPTransferStateBase* state = CSVPTransferIdleState::NewLC();
+    User::LeaveIfError( iStates->Insert(
+            state, KSVPTransferIdleStateIndex ) );
+    CleanupStack::Pop( state );
+    
+    // Pending state
+    state = CSVPTransferPendingState::NewLC();
+    User::LeaveIfError( iStates->Insert(
+            state, KSVPTransferPendingStateIndex ) );
+    CleanupStack::Pop( state );
+    
+    // Accepted state
+    state = CSVPTransferAcceptedState::NewLC();
+    User::LeaveIfError( iStates->Insert(
+            state, KSVPTransferAcceptedStateIndex ) );
+    CleanupStack::Pop( state );
+    
+    // Terminating state
+    state = CSVPTransferTerminatingState::NewLC();
+    User::LeaveIfError( iStates->Insert(
+            state, KSVPTransferTerminatingStateIndex ) );
+    CleanupStack::Pop( state );
+    
+    // Terminated state
+    state = CSVPTransferTerminatedState::NewLC();
+    User::LeaveIfError( iStates->Insert(
+            state, KSVPTransferTerminatedStateIndex ) );
+    CleanupStack::Pop( state );
+    }
+
+// -----------------------------------------------------------------------------
+// CSVPTransferStateContext::IsStateTransitionAccepted
+// -----------------------------------------------------------------------------
+//
+TBool CSVPTransferStateContext::IsStateTransitionAccepted(
+        const TSVPTransferStateIndex aNewState )
+	{
+	TSVPTransferStateIndex current = CurrentState();
+	
+    SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: current  = %d", current )
+    SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: newstate = %d", aNewState )
+    
+    switch( current )
+        {
+        case KErrNotFound:
+            {
+            // Only idle state can be the first one.
+            if ( KSVPTransferIdleStateIndex  == aNewState )
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        case KSVPTransferIdleStateIndex:
+            {
+            if ( KSVPTransferPendingStateIndex == aNewState ||
+                 KSVPTransferTerminatingStateIndex == aNewState )
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        case KSVPTransferPendingStateIndex:
+            {
+            if ( KSVPTransferAcceptedStateIndex == aNewState ||
+                 KSVPTransferTerminatingStateIndex == aNewState )
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        case KSVPTransferAcceptedStateIndex:
+            {
+            // If in accepted state, new transition is valid (return true).
+            // No transition actually occurs because
+            // state "changes" from accepted to accepted.
+            // This ignores sequent icoming NOTIFY's after REFER has been sent.
+            if ( KSVPTransferTerminatingStateIndex == aNewState ||
+                    KSVPTransferAcceptedStateIndex == aNewState)
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        case KSVPTransferTerminatingStateIndex:
+            {
+            // From terminating state, transition to terminated is accepted.
+            if ( KSVPTransferTerminatingStateIndex == aNewState ||
+                 KSVPTransferTerminatedStateIndex == aNewState )
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        case KSVPTransferTerminatedStateIndex:
+            {
+            // From terminated state, transition to idle is accepted.
+            if ( KSVPTransferIdleStateIndex == aNewState )
+                {
+                return ETrue;
+                }
+            else
+                {
+                return EFalse;
+                }
+            }
+        
+        default:
+            {
+            // Should not come here, since all the states are handled
+            SVPDEBUG1( "CSVPTransferStateContext::IsStateTransitionAccepted - Error" )
+            return EFalse;
+            }
+        // No breaks in switch case due returns.  
+        }
+	}
+