sipvoipprovider/svptransfer/src/svptransferstatecontext.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
equal deleted inserted replaced
20:65a3ef1d5bd0 21:f742655b05bf
     1 /*
       
     2 * Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Transfer state context class for state machine
       
    15 *
       
    16 */
       
    17 
       
    18 #include <mcetransactiondatacontainer.h> // TMceTransactionDataContainer 
       
    19 #include <mceoutrefer.h>                 // CMceRefer, CMceOutRefer
       
    20 #include <mceoutevent.h>                 // CMceEvent
       
    21 #include <escapeutils.h>
       
    22 #include <mcesession.h>
       
    23 #include <crcseprofileentry.h>
       
    24 #include <crcseprofileregistry.h>
       
    25 
       
    26 #include "svpsessionbase.h"
       
    27 #include "svptransferstatecontext.h"
       
    28 #include "svptransferstatebase.h"
       
    29 #include "svptransferidlestate.h"
       
    30 #include "svptransferpendingstate.h"
       
    31 #include "svptransferacceptedstate.h"
       
    32 #include "svptransferterminatingstate.h"
       
    33 #include "svptransferterminatedstate.h" 
       
    34 #include "svptransferobserver.h"
       
    35 #include "svplogger.h"          
       
    36 #include "svpuriparser.h"
       
    37 #include "svpconsts.h"
       
    38 #include "svpholdcontext.h"
       
    39 #include "svpholdcontroller.h"
       
    40 #include "svpcleanupresetanddestroy.h"
       
    41 
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // C++ default constructor can NOT contain any code, that might leave.
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CSVPTransferStateContext::CSVPTransferStateContext( 
       
    48                                 CMceSession* aMceSession,                                
       
    49                                 CSVPSessionBase* aSVPSession,                                
       
    50                                 TMceTransactionDataContainer& aContainer, 
       
    51                                 MSVPTransferObserver& aObserver ) :
       
    52         iMceSession( aMceSession ),
       
    53         iSVPSession( aSVPSession ),        
       
    54         iTargetSession( NULL ),
       
    55         iContainer( aContainer ),
       
    56         iTransferObserver( aObserver ),
       
    57         iStates( NULL ),
       
    58         iCurrentState( NULL ),
       
    59         iMceRefer( NULL ),        
       
    60         iMceEvent( NULL ),
       
    61         iAttended( EFalse ),
       
    62         iIncomingReferTo ( NULL ),
       
    63         iIncomingReferredBy ( NULL ),
       
    64         iIncomingReplaces (NULL)
       
    65     {
       
    66     }
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // CSVPTransferStateContext::ConstructL
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 void CSVPTransferStateContext::ConstructL() 
       
    73     {
       
    74     SVPDEBUG1( "CSVPTransferStateContext::ConstructL In" )
       
    75     
       
    76     // Create the transfer states in the state array.
       
    77     InitializeStateArrayL();  
       
    78            
       
    79     // Initialize idle state to current state. Note, that it is not
       
    80     // applied yet.
       
    81     SetCurrentStateL( KSVPTransferIdleStateIndex );
       
    82     
       
    83     SVPDEBUG1( "CSVPTransferStateContext::ConstructL Out" )
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CSVPTransferStateContext::NewL
       
    88 // -----------------------------------------------------------------------------
       
    89 CSVPTransferStateContext* CSVPTransferStateContext::NewL( 
       
    90                                 CMceSession* aMceSession,
       
    91                                 CSVPSessionBase* aSVPSession,
       
    92                                 TMceTransactionDataContainer& aContainer, 
       
    93                                 MSVPTransferObserver& aObserver )
       
    94     {    
       
    95     CSVPTransferStateContext* self = new ( ELeave ) CSVPTransferStateContext(
       
    96                                                         aMceSession,
       
    97                                                         aSVPSession,
       
    98                                                         aContainer, 
       
    99                                                         aObserver );
       
   100     
       
   101     CleanupStack::PushL( self );
       
   102     self->ConstructL();
       
   103     CleanupStack::Pop( self );
       
   104 
       
   105     return self;
       
   106     }
       
   107     
       
   108 // ---------------------------------------------------------------------------
       
   109 // CSVPTransferStateContext::~CSVPTransferStateContext
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 CSVPTransferStateContext::~CSVPTransferStateContext()
       
   113     {
       
   114     SVPDEBUG1( "CSVPTransferStateContext::~CSVPTransferStateContext In" )
       
   115     
       
   116     if ( iStates )
       
   117         {
       
   118         iStates->ResetAndDestroy();
       
   119         iStates->Close();
       
   120         delete iStates;
       
   121         }
       
   122     
       
   123     delete iMceEvent;
       
   124     delete iMceRefer;
       
   125     delete iIncomingReferTo;
       
   126     delete iIncomingReferredBy;
       
   127     delete iIncomingReplaces;
       
   128     
       
   129     SVPDEBUG1( "CSVPTransferStateContext::~CSVPTransferStateContext Out" )        
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // CSVPTransferStateContext::SetCurrentStateL
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 void CSVPTransferStateContext::SetCurrentStateL(
       
   137         TSVPTransferStateIndex aStateIndex )
       
   138     {
       
   139     // Check, if the transition is valid
       
   140     if ( !IsStateTransitionAccepted( aStateIndex ) )
       
   141         {
       
   142         SVPDEBUG2( "CSVPTransferStateContext::SetCurrentStateL: STATE ERROR stateindex: %i", aStateIndex )
       
   143         User::Leave( KSVPErrTransferStateError );
       
   144         }
       
   145     else
       
   146         {
       
   147         iCurrentState = ( *iStates )[ aStateIndex ];
       
   148         iCurrentState->Enter( *this );
       
   149         }
       
   150     }
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // CSVPTransferStateContext::CurrentState
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 TSVPTransferStateIndex CSVPTransferStateContext::CurrentState() const
       
   157     {
       
   158     return iStates->Find( iCurrentState );    
       
   159     }
       
   160 
       
   161 // ---------------------------------------------------------------------------
       
   162 // CSVPTransferStateContext::ApplyCurrentStateL
       
   163 // ---------------------------------------------------------------------------
       
   164 //
       
   165 void CSVPTransferStateContext::ApplyCurrentStateL()
       
   166    {
       
   167    iCurrentState->ApplyL( *this );
       
   168    }
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CSVPTransferStateContext::TransferObserver
       
   172 // ---------------------------------------------------------------------------
       
   173 //
       
   174 MSVPTransferObserver& CSVPTransferStateContext::TransferObserver()
       
   175     {
       
   176     return iTransferObserver;    
       
   177     }
       
   178 
       
   179 // ---------------------------------------------------------------------------
       
   180 // CSVPTransferStateContext::SetMceSessionObject
       
   181 // ---------------------------------------------------------------------------
       
   182 //
       
   183 void CSVPTransferStateContext::SetMceSessionObject( CMceSession* aSession )
       
   184     {
       
   185     iMceSession = aSession;
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // CSVPTransferStateContext::MceSessionObject
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 CMceSession* CSVPTransferStateContext::MceSessionObject()
       
   193     {
       
   194     return iMceSession;
       
   195     }
       
   196 
       
   197 // ---------------------------------------------------------------------------
       
   198 // CSVPTransferStateContext::SetMceRefer
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 void CSVPTransferStateContext::SetMceRefer( CMceRefer* aRefer )
       
   202     {
       
   203     if ( iMceRefer != aRefer )
       
   204         {
       
   205         delete iMceRefer;
       
   206         iMceRefer = aRefer;
       
   207         }
       
   208     }
       
   209 
       
   210 // ---------------------------------------------------------------------------
       
   211 // CSVPTransferStateContext::MceRefer
       
   212 // ---------------------------------------------------------------------------
       
   213 //
       
   214 CMceRefer* CSVPTransferStateContext::MceRefer()
       
   215     {
       
   216     return iMceRefer;
       
   217     }
       
   218 
       
   219 // ---------------------------------------------------------------------------
       
   220 // CSVPTransferStateContext::SetAttended
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 void CSVPTransferStateContext::SetAttended( const TBool aAttended )
       
   224     {
       
   225     iAttended = aAttended;
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------------------------
       
   229 // CSVPTransferStateContext::IsAttended
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 TBool CSVPTransferStateContext::IsAttended()
       
   233     {
       
   234     return iAttended;
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
       
   238 // CSVPTransferStateContext::CheckIsSessionRemoteHold
       
   239 // ---------------------------------------------------------------------------
       
   240 //
       
   241 TBool CSVPTransferStateContext::CheckIsSessionRemoteHold()
       
   242     {
       
   243     SVPDEBUG1( "CSVPTransferStateContext::CheckIsSessionRemoteHold In" )
       
   244     
       
   245     TBool ret = EFalse;
       
   246     
       
   247     if ( iSVPSession->HasHoldController() &&
       
   248          MCCPCallObserver::ECCPStateDisconnecting != iSVPSession->State() )
       
   249         {
       
   250         SVPDEBUG1("CSVPTransferStateContext::CheckIsSessionRemoteHold, Check hold state" )
       
   251         
       
   252         if ( ESVPOnHold == iSVPSession->HoldController().HoldState() &&
       
   253              ESVPRemoteHold == iSVPSession->HoldController().HoldRequest() )
       
   254             {
       
   255             // Session is remote holded -> Snom/EyeBeam as unattended transferer case.
       
   256             SVPDEBUG1( "CSVPTransferStateContext:CheckIsSessionRemoteHold, transferer is Snom, EyeBeam or similar" )
       
   257             ret = ETrue;
       
   258             }
       
   259         }
       
   260     
       
   261     SVPDEBUG2("CSVPTransferStateContext::CheckIsSessionRemoteHold Out return: %d",ret )
       
   262     return ret;
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // CSVPTransferStateContext::SetTransferDataL
       
   267 // ---------------------------------------------------------------------------
       
   268 //
       
   269 void CSVPTransferStateContext::SetTransferDataL(
       
   270         CDesC8Array* aUserAgentHeaders, TInt aSecureStatus )
       
   271     {
       
   272     SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL In" )
       
   273     
       
   274     if ( aUserAgentHeaders )
       
   275         {
       
   276         if ( iIncomingReplaces && IsAttended() )
       
   277             {
       
   278             SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL: Add replaces header" )
       
   279             // fetch "replaces:" string
       
   280             HBufC* replacesStringHeap16 = IncomingReplaces().AllocLC(); // CS: 1
       
   281             
       
   282             // Copy incoming replaces to 8-bit buffer
       
   283             HBufC8* replacesStringHeap8 =
       
   284                     HBufC8::NewLC( replacesStringHeap16->Length() +
       
   285                                    KSVPReplacesColonTxt().Length() ); // CS: 2
       
   286             
       
   287             replacesStringHeap8->Des().Copy( *replacesStringHeap16 );
       
   288             CleanupStack::Pop( 1 );
       
   289             CleanupStack::PushL( replacesStringHeap8 ); // ReAlloc possible
       
   290             
       
   291             // add replaces header
       
   292             replacesStringHeap8->Des().Insert( 0, KSVPReplacesColonTxt );
       
   293             CleanupStack::Pop( 1 );
       
   294             CleanupStack::PushL( replacesStringHeap8 ); // ReAlloc possible
       
   295             SVPDEBUG2( "CSVPTransferStateContext::SetTransferDataL - length: %d", replacesStringHeap8->Length() )
       
   296             
       
   297             // Finally add collected Replaces string to header
       
   298             aUserAgentHeaders->AppendL( *replacesStringHeap8 );
       
   299             CleanupStack::PopAndDestroy( replacesStringHeap8 );      // CS: 1
       
   300             CleanupStack::PopAndDestroy( replacesStringHeap16 );     // CS: 0
       
   301             }
       
   302         
       
   303         if ( iIncomingReferredBy )
       
   304             {
       
   305             SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL: Add referredBy header" )
       
   306             TBuf8<KSVPTempStringlength> referredByString;
       
   307             referredByString.Append( KSVPReferredBy );
       
   308             // add IncomingReferredBy
       
   309             referredByString.Append( IncomingReferredBy() );
       
   310             // Finally add collected Referred-By string to header
       
   311             aUserAgentHeaders->AppendL( referredByString );
       
   312             }
       
   313         }
       
   314     
       
   315     // Update transfer target address according preferred securesetting.
       
   316     UpdateTransferTargetL( aSecureStatus );
       
   317     
       
   318     SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL Out" )
       
   319     }
       
   320 
       
   321 // ---------------------------------------------------------------------------
       
   322 // CSVPTransferStateContext::IsIncoming
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 TBool CSVPTransferStateContext::IsIncoming()
       
   326     {
       
   327     return ( NULL != iIncomingReferTo );
       
   328     }
       
   329 
       
   330 // ---------------------------------------------------------------------------
       
   331 // CSVPTransferStateContext::SetIncomingReferToL
       
   332 // ---------------------------------------------------------------------------
       
   333 //
       
   334 void CSVPTransferStateContext::SetIncomingReferToL( const TDesC8& aReferTo )
       
   335     {
       
   336     SVPDEBUG1("CSVPTransferStateContext::SetIncomingReferToL In" )
       
   337     
       
   338     ResetIncomingReferTo();
       
   339     
       
   340     // modify aReferTo
       
   341     HBufC8* referTo = CompleteReferToL( aReferTo );
       
   342     CleanupStack::PushL( referTo );
       
   343 
       
   344     // at this point referto must contains legal sip uri
       
   345     RemoveExtraParameters( referTo );
       
   346     
       
   347     // Check length - moSession construct limitation
       
   348     // sip: or sips: prefix will be added later, so 95 is maximum
       
   349     if ( referTo->Length() < ( KSVPMaxUriLength - KSVPSipPrefixLength ) )
       
   350         {
       
   351         // Copy and convert the "refer to" -parameter.
       
   352         iIncomingReferTo = HBufC::NewL( referTo->Length() );
       
   353         TPtr temp = iIncomingReferTo->Des();
       
   354         temp.Copy( *referTo );
       
   355         }
       
   356     else
       
   357         {
       
   358         SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL: referTo too long, Leave" )
       
   359         User::Leave( KErrArgument );
       
   360         }
       
   361     
       
   362     CleanupStack::PopAndDestroy( referTo );
       
   363     
       
   364    SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferToL lenght: %d",
       
   365             iIncomingReferTo->Length())
       
   366     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL Out" )
       
   367     }
       
   368 
       
   369 // -----------------------------------------------------------------------------
       
   370 // CSVPSessionBase::SetIncomingReferredByL
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 void CSVPTransferStateContext::SetIncomingReferredByL( const TDesC8& aReferredBy )
       
   374     {
       
   375     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL In" )
       
   376     
       
   377     ResetIncomingReferredBy();
       
   378     
       
   379     // modify aReferredBy
       
   380     HBufC8* referredBy = CompleteReferredByL( aReferredBy );
       
   381     CleanupStack::PushL( referredBy );
       
   382     
       
   383     // Copy and convert the "Referred By" -parameter.    
       
   384     iIncomingReferredBy = HBufC::NewL( referredBy->Length() );
       
   385     TPtr temp = iIncomingReferredBy->Des();
       
   386     temp.Copy( *referredBy );
       
   387     CleanupStack::PopAndDestroy( referredBy );
       
   388     
       
   389     SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferredByL lenght: %d",
       
   390             iIncomingReferredBy->Length() )
       
   391     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL Out" )
       
   392     }    
       
   393 
       
   394 // ---------------------------------------------------------------------------
       
   395 // CSVPTransferStateContext::SetIncomingReplacesL
       
   396 // ---------------------------------------------------------------------------
       
   397 //
       
   398 void CSVPTransferStateContext::SetIncomingReplacesL( const TDesC8& aString )
       
   399     { 
       
   400     SVPDEBUG1("CSVPTransferStateContext::SetIncomingReplacesL In" )
       
   401     
       
   402     ResetIncomingReplaces();
       
   403     
       
   404     // modify Replaces
       
   405     HBufC8* string = CompleteReplacesL( aString );
       
   406     CleanupStack::PushL( string );
       
   407     
       
   408     // Copy and convert the "Replaces" -parameter.    
       
   409     iIncomingReplaces = HBufC::NewL( string->Length() );
       
   410     TPtr temp = iIncomingReplaces->Des();
       
   411     temp.Copy( *string );
       
   412     CleanupStack::PopAndDestroy( string );
       
   413     
       
   414     SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReplacesL lenght: %d",
       
   415             iIncomingReplaces->Length() )
       
   416     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReplacesL Out" )
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // CSVPTransferStateContext::CompleteReplacesL
       
   421 // ---------------------------------------------------------------------------
       
   422 //
       
   423 HBufC8* CSVPTransferStateContext::CompleteReplacesL( const TDesC8& aString )
       
   424     {
       
   425     SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL In" )
       
   426     
       
   427     // Copy the parameter to a new buffer.
       
   428     HBufC8* string = aString.AllocLC();
       
   429     // If "?Replaces=" found attended transfer case
       
   430     TInt position = CheckReplacesTxt( *string );
       
   431     SVPDEBUG2( "    CheckReplacesTxt returns = %d", position );
       
   432     
       
   433     if ( KErrNotFound != position )
       
   434         {
       
   435         TakeReplacesTxt( string, position );
       
   436         CleanupStack::Pop( 1 ); // string, ReAlloc possible
       
   437         CleanupStack::PushL( string );
       
   438         }
       
   439     // Check "?X-Sipx-Authidentity=" and remove text after it if exists
       
   440     position = CheckAuthidentity( *string );
       
   441 
       
   442     if ( KErrNotFound != position )
       
   443         {
       
   444         // "?X-Sipx-Authidentity=" found
       
   445         CutStringFromPosition( string, position );
       
   446         CleanupStack::Pop( 1 ); // string, ReAlloc possible
       
   447         CleanupStack::PushL( string );
       
   448         }
       
   449     
       
   450     // Check ">" and remove text after it if exists
       
   451     position = CheckRightBracket( *string );
       
   452     SVPDEBUG2("    CheckRightBracket returns = %d" , position )
       
   453     
       
   454     if ( KErrNotFound != position )
       
   455         {
       
   456         // ">" found
       
   457         CutStringFromPosition( string, position );
       
   458         CleanupStack::Pop( 1 ); // string, ReAlloc possible
       
   459         CleanupStack::PushL( string );
       
   460         }
       
   461     
       
   462     HBufC8* temp = EscapeUtils::EscapeDecodeL( *string );
       
   463     CleanupStack::PopAndDestroy( string );
       
   464     
       
   465     SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL Out" )
       
   466     return temp;
       
   467     }
       
   468 
       
   469 // ---------------------------------------------------------------------------
       
   470 // CSVPTransferStateContext::CompleteReferToL
       
   471 // ---------------------------------------------------------------------------
       
   472 //
       
   473 HBufC8* CSVPTransferStateContext::CompleteReferToL( const TDesC8& aUri )
       
   474     {
       
   475     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL In" )
       
   476     
       
   477     // Copy the parameter to a new buffer.
       
   478     HBufC8* uri = aUri.AllocLC();
       
   479     
       
   480     // Check "<" and remove it and text before it if exists
       
   481     TInt position = CheckLeftBracket( *uri );
       
   482     
       
   483     if ( KErrNotFound != position )
       
   484         {
       
   485         RemoveLeftBracket( uri, position );
       
   486         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   487         CleanupStack::PushL( uri );
       
   488         }
       
   489     
       
   490     // Check ";user=phone" and remove if exists
       
   491     position = CheckUserEqualsPhone( *uri );
       
   492     
       
   493     if ( KErrNotFound != position )
       
   494         {
       
   495         // ";user=phone" found
       
   496         RemoveUserEqualsPhone( uri, position );
       
   497         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   498         CleanupStack::PushL( uri );
       
   499         }
       
   500     
       
   501     // Check ">" and remove text after it if exists
       
   502     position = CheckRightBracket( *uri );
       
   503     
       
   504     if ( KErrNotFound != position )
       
   505         {
       
   506         // ">" found
       
   507         CutStringFromPosition( uri, position );
       
   508         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   509         CleanupStack::PushL( uri );
       
   510         }
       
   511     
       
   512     // Check "KSVPQuesReplacesTxt" and remove text after it if exists
       
   513     // If it is found -> attended transfer case
       
   514     position = CheckReplacesTxt( *uri );
       
   515     
       
   516     if ( KErrNotFound != position )
       
   517         {
       
   518         // Found -> attended case.
       
   519         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= found -> attended transfer" )
       
   520         SetAttended( ETrue );
       
   521         SetIncomingReplacesL( aUri );
       
   522         CutStringFromPosition( uri, position );
       
   523         }
       
   524     else
       
   525         {
       
   526         // Not found -> unattended case.
       
   527         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= not found -> unattended transfer" )
       
   528         SetAttended( EFalse );
       
   529         }
       
   530 
       
   531     // Check "?X-Sipx-Authidentity=" and remove text after it if exists
       
   532     position = CheckAuthidentity( *uri );
       
   533 
       
   534     if ( KErrNotFound != position )
       
   535         {
       
   536         // "?X-Sipx-Authidentity=" found
       
   537         CutStringFromPosition( uri, position );
       
   538         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   539         CleanupStack::PushL( uri );
       
   540         }
       
   541 
       
   542     // Check "sip:" and remove it if exists
       
   543     if ( KErrNone == uri->Find( KSVPSipPrefix ) )
       
   544         {
       
   545         // sip: is in the beginning of the string
       
   546         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sip:" )
       
   547         uri->Des().Delete( 0, KSVPSipPrefixLength );
       
   548         }
       
   549 
       
   550     // Check "sips:" and remove it if exists
       
   551     if ( KErrNone == uri->Find( KSVPSipsPrefix ) )
       
   552         {
       
   553         // sips: is in the beginning of the string
       
   554         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sips:" )
       
   555         uri->Des().Delete( 0, KSVPSipsPrefixLength );
       
   556         }
       
   557 
       
   558     // Check ":" and remove text after it if exists,
       
   559     // some server might add this after transfer target address
       
   560     position = uri->Find( KSVPCln );
       
   561 
       
   562     if ( KErrNotFound != position )
       
   563         {
       
   564         // ":" found
       
   565         SVPDEBUG2( "CSVPTransferStateContext::CompleteReferToL remove text after %d ", position )
       
   566         uri->Des().Delete( position, uri->Length() - position );
       
   567         }
       
   568 
       
   569     CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   570     
       
   571     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL Out" )
       
   572     return uri;
       
   573     }
       
   574 
       
   575 // ---------------------------------------------------------------------------
       
   576 // CSVPTransferStateContext::CompleteReferredByL
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 HBufC8* CSVPTransferStateContext::CompleteReferredByL(
       
   580         const TDesC8& aReferredBy )
       
   581     {
       
   582     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL In" )
       
   583     
       
   584     // Copy the parameter to a new buffer.
       
   585     HBufC8* referredBy = aReferredBy.AllocLC();
       
   586     
       
   587     // Check "Referred-By:" and remove it
       
   588     TInt position = CheckReferredByTxt( *referredBy );
       
   589     
       
   590     if ( KErrNotFound != position )
       
   591         {
       
   592         // "Referred-By:" found.
       
   593         RemoveReferredByTxt( referredBy, position );
       
   594         }
       
   595     
       
   596     CleanupStack::Pop( 1 ); // referredBy, ReAlloc possible
       
   597     
       
   598     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL Out" )
       
   599     return referredBy;
       
   600     }
       
   601 
       
   602 // ---------------------------------------------------------------------------
       
   603 // CSVPTransferStateContext::CheckUserEqualsPhone
       
   604 // ---------------------------------------------------------------------------
       
   605 //
       
   606 TInt CSVPTransferStateContext::CheckUserEqualsPhone( const TDesC8& aUri ) const
       
   607     {
       
   608     SVPDEBUG1( "CSVPTransferStateContext::CheckUserEqualsPhone" )
       
   609     
       
   610     return ( aUri.FindF( KSVPUserEqualsPhone ) );
       
   611     }
       
   612 
       
   613 // ---------------------------------------------------------------------------
       
   614 // CSVPTransferStateContext::RemoveUserEqualsPhone
       
   615 // ---------------------------------------------------------------------------
       
   616 //
       
   617 void CSVPTransferStateContext::RemoveUserEqualsPhone(
       
   618         HBufC8*& aUri, TInt aPosition ) const
       
   619     {
       
   620     SVPDEBUG2( "CSVPTransferStateContext::RemoveUserEqualsPhone posit = %d", aPosition )
       
   621     
       
   622     aUri->Des().Delete( aPosition, KSVPUserEqualsPhoneLenght );
       
   623     }
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 // CSVPTransferStateContext::RemoveExtraParameters
       
   627 // ---------------------------------------------------------------------------
       
   628 //
       
   629 void CSVPTransferStateContext::RemoveExtraParameters( HBufC8*& aUri ) const 
       
   630     {
       
   631     SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters In" )
       
   632     
       
   633     // remove all extra parameters from given address
       
   634     TInt index = aUri->Locate( KSVPSemiColonMark );
       
   635     TInt bracketLocation = KErrNotFound;
       
   636     
       
   637     SVPDEBUG3( "CSVPTransferStateContext::RemoveExtraParameters index = %d, length = %d",
       
   638         index, aUri->Length() )
       
   639     
       
   640     if ( KErrNotFound != index )
       
   641         {
       
   642         // Delete ";" and text after it
       
   643         aUri->Des().Delete( index, aUri->Length() );
       
   644         }
       
   645     
       
   646     // Check "<" and remove it and text before it if exists
       
   647     bracketLocation = CheckLeftBracket( *aUri );
       
   648     
       
   649     if ( KErrNotFound != bracketLocation )
       
   650         {
       
   651         RemoveLeftBracket( aUri, bracketLocation );
       
   652         }
       
   653     
       
   654     // Check ">" and remove text after it if exists
       
   655     bracketLocation = CheckRightBracket( *aUri );
       
   656     
       
   657     if ( KErrNotFound != bracketLocation )
       
   658         {
       
   659         CutStringFromPosition( aUri, bracketLocation );
       
   660         }
       
   661     
       
   662     SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters Out" )
       
   663     }
       
   664 
       
   665 // ---------------------------------------------------------------------------
       
   666 // CSVPTransferStateContext::CheckReplacesTxt
       
   667 // ---------------------------------------------------------------------------
       
   668 //
       
   669 TInt CSVPTransferStateContext::CheckReplacesTxt( const TDesC8& aUri ) const
       
   670     {
       
   671     SVPDEBUG1( "CSVPTransferStateContext::CheckReplacesTxt" )
       
   672     
       
   673     return ( aUri.FindF( KSVPQuesReplacesTxt ) );
       
   674     }
       
   675 
       
   676 // ---------------------------------------------------------------------------
       
   677 // CSVPTransferStateContext::CutStringFromPosition
       
   678 // ---------------------------------------------------------------------------
       
   679 //
       
   680 void CSVPTransferStateContext::CutStringFromPosition(
       
   681         HBufC8*& aUri, TInt aPosition ) const
       
   682     {
       
   683     SVPDEBUG2( "CSVPTransferStateContext::CutStringFromPosition posit = %d", aPosition )
       
   684     aUri->Des().Delete( aPosition, aUri->Length() - aPosition );
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------------------------
       
   688 // CSVPTransferStateContext::CheckReferredByTxt
       
   689 // ---------------------------------------------------------------------------
       
   690 //
       
   691 TInt CSVPTransferStateContext::CheckReferredByTxt(
       
   692         const TDesC8& aReferredBy ) const
       
   693     {
       
   694     SVPDEBUG1( "CSVPTransferStateContext::CheckReferredByTxt" )
       
   695     
       
   696     return ( aReferredBy.FindF( KSVPReferredBy ) );
       
   697     }
       
   698 
       
   699 // ---------------------------------------------------------------------------
       
   700 // CSVPTransferStateContext::RemoveReferredByTxt
       
   701 // ---------------------------------------------------------------------------
       
   702 //
       
   703 void CSVPTransferStateContext::RemoveReferredByTxt(
       
   704         HBufC8*& aReferredBy, TInt aPosition ) const
       
   705     {
       
   706     SVPDEBUG2( "CSVPTransferStateContext::RemoveReferredByTxt posit = %d", aPosition )
       
   707     
       
   708     aReferredBy->Des().Delete( aPosition, KSVPReferredByLength + 1 );
       
   709     }
       
   710 
       
   711 // ---------------------------------------------------------------------------
       
   712 // CSVPTransferStateContext::TakeReplacesTxt
       
   713 // ---------------------------------------------------------------------------
       
   714 //
       
   715 void CSVPTransferStateContext::TakeReplacesTxt(
       
   716         HBufC8*& aString, TInt aPosition ) const
       
   717     {
       
   718     SVPDEBUG2( "CSVPTransferStateContext::TakeReplacesTxt posit = %d", aPosition )
       
   719     
       
   720     aString->Des().Delete( 0, aPosition + KSVPQuesReplacesTxtLength );
       
   721     }
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // CSVPTransferStateContext::CheckLeftBracket
       
   725 // ---------------------------------------------------------------------------
       
   726 //
       
   727 TInt CSVPTransferStateContext::CheckLeftBracket( const TDesC8& aUri ) const
       
   728     {
       
   729     SVPDEBUG1( "CSVPTransferStateContext::CheckLeftBracket" )
       
   730     
       
   731     // Return position of "<" or KErrNotFound
       
   732     return ( aUri.Find( KSVPLeftBracketMark ) );
       
   733     }
       
   734 
       
   735 // ---------------------------------------------------------------------------
       
   736 // CSVPTransferStateContext::RemoveLeftBracket
       
   737 // ---------------------------------------------------------------------------
       
   738 //
       
   739 void CSVPTransferStateContext::RemoveLeftBracket(
       
   740         HBufC8*& aUri, TInt aPosition ) const
       
   741     {
       
   742     SVPDEBUG2( "CSVPTransferStateContext::RemoveLeftBracket posit = %d", aPosition )
       
   743     
       
   744     aUri->Des().Delete( 0, aPosition + KSVPSingleBracketLength );
       
   745     }
       
   746 
       
   747 // ---------------------------------------------------------------------------
       
   748 // CSVPTransferStateContext::CheckRightBracket
       
   749 // ---------------------------------------------------------------------------
       
   750 //
       
   751 TInt CSVPTransferStateContext::CheckRightBracket( const TDesC8& aUri ) const
       
   752     {
       
   753     SVPDEBUG1( "CSVPTransferStateContext::CheckRightBracket" )
       
   754     
       
   755     return ( aUri.Find( KSVPRightBracketMark ) );
       
   756     }
       
   757 
       
   758 // ---------------------------------------------------------------------------
       
   759 // CSVPTransferStateContext::CheckAuthidentity  
       
   760 // ---------------------------------------------------------------------------
       
   761 //
       
   762 TInt CSVPTransferStateContext::CheckAuthidentity( const TDesC8& aUri ) const
       
   763     {
       
   764     SVPDEBUG1( "CSVPTransferStateContext::CheckAuthidentity" )
       
   765     TInt returnValue = aUri.Find( KSVPAuthidentity );
       
   766     SVPDEBUG2( "CSVPTransferStateContext::CheckAuthidentity return: %d", returnValue )
       
   767     if ( returnValue == KErrNotFound )
       
   768         {
       
   769         returnValue = aUri.Find( KSVPAuthidentity2 );
       
   770         SVPDEBUG2( "CSVPTransferStateContext::CheckAuthidentity second return: %d", returnValue )
       
   771         }
       
   772     if ( returnValue == KErrNotFound )
       
   773         {
       
   774         returnValue = aUri.Find( KSVPAuthidentity3 );
       
   775         SVPDEBUG2( "CSVPTransferStateContext::CheckAuthidentity third return: %d", returnValue )
       
   776         }
       
   777     return returnValue;
       
   778     }
       
   779 
       
   780 // ---------------------------------------------------------------------------
       
   781 // CSVPTransferStateContext::IncomingReferTo
       
   782 // ---------------------------------------------------------------------------
       
   783 //
       
   784 const TDesC& CSVPTransferStateContext::IncomingReferTo()
       
   785     {
       
   786     SVPDEBUG1( "CSVPTransferStateContext::IncomingReferTo" )
       
   787     
       
   788     return *iIncomingReferTo;
       
   789     }
       
   790 
       
   791 // ---------------------------------------------------------------------------
       
   792 // CSVPTransferStateContext::UpdateTransferTargetL
       
   793 // ---------------------------------------------------------------------------
       
   794 //
       
   795 void CSVPTransferStateContext::UpdateTransferTargetL( TInt aSecureStatus )
       
   796     {
       
   797     SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL In" )
       
   798     
       
   799     if ( iIncomingReferTo )
       
   800         {
       
   801         if ( KSVPStatusNonSecure == aSecureStatus )
       
   802             {
       
   803             SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIP uri" )
       
   804             
       
   805             // Check "sips:" and remove it if exists
       
   806             if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
       
   807                 {
       
   808                 // sips: is in the beginning of the string, position 0
       
   809                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sips:" )
       
   810                 iIncomingReferTo->Des().Delete( 0, KSVPSipsPrefixLength );
       
   811                 }
       
   812             
       
   813             // Add "sip:" prefix in the beginning of the string, if it's missing.
       
   814             if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
       
   815                 {
       
   816                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sip:" )
       
   817                 iIncomingReferTo = iIncomingReferTo->ReAllocL(
       
   818                         iIncomingReferTo->Length() + KSVPSipPrefixLength );
       
   819                 iIncomingReferTo->Des().Insert( 0, KSVPSipPrefix2 );
       
   820                 }
       
   821             }
       
   822         else
       
   823             {
       
   824             SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIPS" )
       
   825             
       
   826             // Check "sip:" and remove it if exists
       
   827             if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
       
   828                 {
       
   829                 // sip: is in the beginning of the string
       
   830                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sip:" )
       
   831                 iIncomingReferTo->Des().Delete( 0, KSVPSipPrefixLength );
       
   832                 }
       
   833             
       
   834             // Add "sips:" prefix in the beginning of the string, if it's missing.
       
   835             if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
       
   836                 {
       
   837                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sips:" )
       
   838                 iIncomingReferTo = iIncomingReferTo->ReAllocL(
       
   839                         iIncomingReferTo->Length() + KSVPSipsPrefixLength );
       
   840                 iIncomingReferTo->Des().Insert( 0, KSVPSipsPrefix2 );
       
   841                 }
       
   842             }
       
   843         }
       
   844     else
       
   845         {
       
   846         SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL IncomingReferTo Not OK" )
       
   847         }
       
   848     
       
   849     SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL Out" )
       
   850     }
       
   851 
       
   852 // ---------------------------------------------------------------------------
       
   853 // CSVPTransferStateContext::ResetIncomingReferTo
       
   854 // ---------------------------------------------------------------------------
       
   855 //
       
   856 void CSVPTransferStateContext::ResetIncomingReferTo()
       
   857     {
       
   858     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferTo" )    
       
   859     
       
   860     if ( iIncomingReferTo )
       
   861         {
       
   862         delete iIncomingReferTo;
       
   863         iIncomingReferTo = NULL;
       
   864         }
       
   865     }
       
   866 
       
   867 // ---------------------------------------------------------------------------
       
   868 // CSVPTransferStateContext::ResetIncomingReferredBy
       
   869 // ---------------------------------------------------------------------------
       
   870 //
       
   871 void CSVPTransferStateContext::ResetIncomingReferredBy()
       
   872     {
       
   873     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferredBy" )
       
   874     
       
   875     if ( iIncomingReferredBy )
       
   876         {
       
   877         delete iIncomingReferredBy;
       
   878         iIncomingReferredBy = NULL;
       
   879         }
       
   880     }
       
   881 
       
   882 // ---------------------------------------------------------------------------
       
   883 // CSVPTransferStateContext::IncomingReferredBy
       
   884 // ---------------------------------------------------------------------------
       
   885 //
       
   886 const TDesC& CSVPTransferStateContext::IncomingReferredBy()
       
   887     {
       
   888     SVPDEBUG1( "CSVPTransferStateContext::IncomingReferredBy" )
       
   889     
       
   890     return *iIncomingReferredBy;
       
   891     }
       
   892 
       
   893 // ---------------------------------------------------------------------------
       
   894 // CSVPTransferStateContext::IncomingReplaces
       
   895 // ---------------------------------------------------------------------------
       
   896 //
       
   897 const TDesC& CSVPTransferStateContext::IncomingReplaces()
       
   898     {
       
   899     SVPDEBUG1( "CSVPTransferStateContext::IncomingReplaces" )
       
   900     
       
   901     return *iIncomingReplaces;
       
   902     }
       
   903 
       
   904 // ---------------------------------------------------------------------------
       
   905 // CSVPTransferStateContext::ResetIncomingReplaces
       
   906 // ---------------------------------------------------------------------------
       
   907 //
       
   908 void CSVPTransferStateContext::ResetIncomingReplaces()
       
   909     {
       
   910     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReplaces" )
       
   911     
       
   912     if ( iIncomingReplaces )
       
   913         {
       
   914         delete iIncomingReplaces;
       
   915         iIncomingReplaces = NULL;
       
   916         }
       
   917     }
       
   918 
       
   919 // ---------------------------------------------------------------------------
       
   920 // CSVPTransferStateContext::SetTransferParmsL
       
   921 // ---------------------------------------------------------------------------
       
   922 //
       
   923 void CSVPTransferStateContext::SetTransferParmsL(
       
   924         CSVPSessionBase* aTargetSession, const TDesC& aTarget,
       
   925         const TBool aAttendedTransfer )
       
   926     {
       
   927     SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL In" )
       
   928     
       
   929     // No target session as default. 
       
   930     iTargetSession = NULL;
       
   931     
       
   932     // Delete possible old refer 
       
   933     delete iMceRefer;
       
   934     iMceRefer = NULL;
       
   935     
       
   936     // Set attended/unattended transfer
       
   937     SetAttended( aAttendedTransfer );
       
   938     
       
   939     // Create mce out refer using given target parameter or call
       
   940     if ( aTarget.Length() > 0 )
       
   941         {
       
   942         CreateMceOutReferL( aTarget );
       
   943         }
       
   944     else
       
   945         {
       
   946         CreateMceOutReferL( aTargetSession );
       
   947         }
       
   948     
       
   949     SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL Out" )
       
   950     }
       
   951 
       
   952 // ---------------------------------------------------------------------------
       
   953 // CSVPTransferStateContext::CreateMceOutReferL
       
   954 // ---------------------------------------------------------------------------
       
   955 //
       
   956 void CSVPTransferStateContext::CreateMceOutReferL( const TDesC& aTarget )
       
   957     {
       
   958     // Create mce out refer using target string (unattended).   
       
   959     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) In" )
       
   960     
       
   961     // Copy 'refer to' argument
       
   962     HBufC8* target = HBufC8::NewLC( aTarget.Length() );
       
   963     target->Des().Copy( aTarget );
       
   964     
       
   965     // Parse target with uri parser, use session recipient as domain source 
       
   966     CSVPUriParser* uriParser = CSVPUriParser::NewLC();
       
   967     HBufC8* referto = NULL;
       
   968     RPointerArray< CRCSEProfileEntry > entryArray;
       
   969     CleanupResetAndDestroy< RPointerArray<CRCSEProfileEntry> >::PushL( entryArray );
       
   970     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC();
       
   971     
       
   972     // Get VoIP profile by service id
       
   973     reg->FindByServiceIdL( iSVPSession->Parameters().ServiceId(), entryArray );
       
   974     __ASSERT_ALWAYS( entryArray.Count(), User::Leave( KErrArgument ) );
       
   975     CRCSEProfileEntry* entry = entryArray[0];
       
   976     uriParser->SetUserEqualsPhoneRequiredL(
       
   977             CRCSEProfileEntry::EOn == entry->iUserPhoneUriParameter );
       
   978     
       
   979     CleanupStack::PopAndDestroy( reg );
       
   980     CleanupStack::PopAndDestroy( &entryArray );
       
   981 
       
   982     HBufC8* recipient = NULL;
       
   983     const CMceSession& session = iSVPSession->Session();
       
   984     __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
       
   985     
       
   986     TBool isCLIROn = iSVPSession->IsCLIROnL();
       
   987     
       
   988     if ( ( iSVPSession->IsMobileOriginated() && !isCLIROn ) 
       
   989             || ( !iSVPSession->IsMobileOriginated() && isCLIROn ) )
       
   990         {
       
   991         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), orig" )
       
   992         const TDesC8& orig = session.Originator(); 
       
   993         __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
       
   994         recipient = HBufC8::NewLC( orig.Length() );
       
   995         recipient->Des().Copy( orig );
       
   996         }
       
   997     else
       
   998         {
       
   999         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), recip" )
       
  1000         const TDesC8& recip = session.Recipient(); 
       
  1001         __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
       
  1002         recipient = HBufC8::NewLC( recip.Length() );
       
  1003         recipient->Des().Copy( recip );    
       
  1004         }
       
  1005 
       
  1006     // remove all extra parameters from recipient address
       
  1007     RemoveExtraParameters( recipient );
       
  1008     
       
  1009     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) recipient->Length() = %d",
       
  1010                recipient->Length() )
       
  1011     
       
  1012     if ( iSVPSession->SecureMandatory() || iSVPSession->SecurePreferred() )
       
  1013         {
       
  1014         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIPS URI..." )
       
  1015         referto = uriParser->CompleteSecureSipUriL( *target, *recipient );
       
  1016         }
       
  1017     else
       
  1018         {
       
  1019         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIP URI..." )
       
  1020         referto = uriParser->CompleteSipUriL( *target, *recipient );
       
  1021         }
       
  1022     
       
  1023     CleanupStack::PushL( referto );
       
  1024     
       
  1025     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 1 referto->Length() = %d",
       
  1026                referto->Length() )
       
  1027     
       
  1028     // remove all extra parameters from referto
       
  1029     RemoveExtraParameters( referto );
       
  1030 
       
  1031     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 2 referto->Length() = %d",
       
  1032                referto->Length() )
       
  1033     
       
  1034     // Create the refer
       
  1035     delete iMceRefer;
       
  1036     iMceRefer = NULL;
       
  1037     iMceRefer = CMceOutRefer::NewL( *iMceSession, *referto, CMceRefer::ENoSuppression );
       
  1038     CleanupStack::PopAndDestroy( referto );
       
  1039     
       
  1040     CleanupStack::PopAndDestroy( recipient );
       
  1041     CleanupStack::PopAndDestroy( uriParser );
       
  1042     CleanupStack::PopAndDestroy( target );
       
  1043     
       
  1044     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) Out" )
       
  1045 	}
       
  1046 
       
  1047 // ---------------------------------------------------------------------------
       
  1048 // CSVPTransferStateContext::CreateMceOutReferL
       
  1049 // ---------------------------------------------------------------------------
       
  1050 //
       
  1051 void CSVPTransferStateContext::CreateMceOutReferL( CSVPSessionBase* aTargetSession )
       
  1052     {
       
  1053     // Create mce out refer using session (attended).   
       
  1054     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) In" )    
       
  1055     
       
  1056     // Store target session 
       
  1057     iTargetSession = aTargetSession;
       
  1058     
       
  1059     // Construct the refer-to string
       
  1060     HBufC8* referto = HBufC8::NewLC( KSVPTempStringlength );
       
  1061     TPtr8 refptr = referto->Des();
       
  1062     
       
  1063     if ( iTargetSession )
       
  1064         {
       
  1065         // Set refer-to for the attended transfer using the target session,
       
  1066         // that can not be the same as the owner session of the 
       
  1067         // transfer controller.
       
  1068         if ( iSVPSession != iTargetSession )
       
  1069             {
       
  1070             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) TargetSession = 0x%x", &iTargetSession )
       
  1071             
       
  1072             HBufC8* recipient = NULL;
       
  1073             const CMceSession& session = iTargetSession->Session();
       
  1074             __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
       
  1075             
       
  1076             if ( iTargetSession->IsMobileOriginated() ) 
       
  1077                 {
       
  1078                 const TDesC8& recip = session.Recipient();
       
  1079                 __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
       
  1080                 recipient = HBufC8::NewLC( recip.Length() );
       
  1081                 recipient->Des().Copy( recip );
       
  1082                 }
       
  1083             else
       
  1084                 {
       
  1085                 const TDesC8& orig = session.Originator();
       
  1086                 __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
       
  1087                 recipient = HBufC8::NewLC( orig.Length() );
       
  1088                 recipient->Des().Copy( orig );    
       
  1089                 }
       
  1090             
       
  1091             // remove all extra parameters from recipient address
       
  1092             RemoveExtraParameters( recipient );
       
  1093             
       
  1094             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) recipient->Length() = %d",
       
  1095                recipient->Length() )
       
  1096             
       
  1097             // Set the refer-to address (recipient)
       
  1098             refptr.Append( recipient->Des() );
       
  1099             CleanupStack::PopAndDestroy( recipient );
       
  1100             
       
  1101             // Gather up the rest of the refer-to data (replaces etc.)  
       
  1102             // from the target session (sessionbase) member variables.
       
  1103             TBuf8<KSVPTempStringlength> tmp( KNullDesC8 );
       
  1104             tmp.Append( KSVPQuesReplacesTxt ); // Set CallId
       
  1105             
       
  1106             if ( iTargetSession->CallId() )
       
  1107                 {
       
  1108                 // Set "replaces" callid string starting from next char 
       
  1109                 // the of KSVPCallId_replaces -text
       
  1110                 TDesC8* callid = iTargetSession->CallId();
       
  1111                 TInt index = callid->Find( KSVPCallId_replaces );
       
  1112                 
       
  1113                 if ( KErrNotFound != index )
       
  1114                     {
       
  1115                     // Check and encode the possible @ char of the callid 
       
  1116                     // to "%40" format. This kind of callid e.g. in Cisco 7960.
       
  1117                     TInt index2 = callid->Find( KSVPAt );
       
  1118                     
       
  1119                     if ( KErrNotFound != index2 )
       
  1120                 	    {
       
  1121                 	    HBufC8* tmpCallId = HBufC8::NewLC( callid->Length() );
       
  1122                 	    tmpCallId->Des().Append( callid->Mid( index +
       
  1123                 	            KSVPCallId_replaces().Length() ) );
       
  1124                 	    CSVPUriParser::EscapeEncodeSipUriL( tmpCallId,
       
  1125                                 EscapeUtils::EEscapeUrlEncoded );
       
  1126                         tmp.Append( *tmpCallId );
       
  1127                         CleanupStack::Pop( 1 ); // tmpCallId, ReAlloc possible
       
  1128                         delete tmpCallId;
       
  1129                         }
       
  1130                     else
       
  1131                         {
       
  1132                         // Normal copy from the correct position
       
  1133                         tmp.Append( callid->Mid( index +
       
  1134                                 KSVPCallId_replaces().Length() ) );
       
  1135                         }
       
  1136                     }
       
  1137                 }
       
  1138             else
       
  1139                 {
       
  1140                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing CallId %i", KSVPErrTransferReferTo )
       
  1141                 User::Leave( KSVPErrTransferReferTo );
       
  1142                 }
       
  1143             
       
  1144             // To-header                    
       
  1145             if ( iTargetSession->ToHeader() )
       
  1146                 {
       
  1147                 tmp.Append( KSVPTo_tag );
       
  1148                 
       
  1149                 // Set "to" tag string starting from next char 
       
  1150                 // of the KSVPTo_tag_replaces -text
       
  1151                 TDesC8* toHdr = iTargetSession->ToHeader();
       
  1152                 TInt index = toHdr->Find( KSVP_tag );
       
  1153                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) toHdr index = %d", index )
       
  1154                 
       
  1155                 if ( KErrNotFound != index )
       
  1156                     {
       
  1157                     tmp.Append( toHdr->Mid( index + KSVPTagLength ) );
       
  1158                     }
       
  1159                 }
       
  1160             else
       
  1161                 {
       
  1162                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing ToHeader %i", KSVPErrTransferReferTo )        
       
  1163                 User::Leave( KSVPErrTransferReferTo );
       
  1164                 }
       
  1165             
       
  1166             // From-header
       
  1167             if ( iTargetSession->FromHeader() )
       
  1168                 {                    
       
  1169                 tmp.Append( KSVPFrom_tag );                    
       
  1170                 
       
  1171                 // Set "from" tag string starting from next char of 
       
  1172                 // the KSVPTo_tag_replaces -text
       
  1173                 TDesC8* fromHdr = iTargetSession->FromHeader();
       
  1174                 TInt index = fromHdr->Find( KSVP_tag );
       
  1175                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) fromHdr index = %d", index )
       
  1176                 
       
  1177                 if ( KErrNotFound != index )
       
  1178                     {
       
  1179                     tmp.Append( fromHdr->Mid( index + KSVPTagLength ) );
       
  1180                     }
       
  1181                 }
       
  1182             else
       
  1183                 {
       
  1184                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing FromHeader %i", KSVPErrTransferReferTo )
       
  1185                 User::Leave( KSVPErrTransferReferTo );
       
  1186                 }
       
  1187             
       
  1188             refptr.Append( tmp );
       
  1189             } // if ( iSVPSession != iTargetSession )
       
  1190         else
       
  1191             {
       
  1192             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - the same target session %i", KSVPErrTransferReferTo )
       
  1193             User::Leave( KSVPErrTransferReferTo );
       
  1194             }
       
  1195         
       
  1196         // Create the refer
       
  1197         iMceRefer = CMceOutRefer::NewL( *iMceSession,
       
  1198                 *referto, CMceRefer::ENoSuppression );
       
  1199         } // if (iTargetSession)
       
  1200     else
       
  1201         {
       
  1202         SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - no target session %i", KSVPErrTransferReferTo )        
       
  1203         User::Leave( KSVPErrTransferReferTo );
       
  1204         }
       
  1205     
       
  1206     CleanupStack::PopAndDestroy( referto );    	
       
  1207     
       
  1208     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) Out" )        
       
  1209 	}
       
  1210 
       
  1211 // ---------------------------------------------------------------------------
       
  1212 // CSVPTransferStateContext::ExecuteReferL
       
  1213 // ---------------------------------------------------------------------------
       
  1214 //
       
  1215 void CSVPTransferStateContext::ExecuteReferL()
       
  1216     {
       
  1217     SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL In" )
       
  1218     
       
  1219     delete iMceEvent;
       
  1220     iMceEvent = NULL;
       
  1221     
       
  1222     // Create headers for refer call.
       
  1223     CDesC8Array* headers = SetupHeadersL();
       
  1224     CleanupStack::PushL( headers );
       
  1225     
       
  1226     // Refer with headers, passes ownership.
       
  1227     iMceEvent = static_cast< CMceOutRefer* >(MceRefer())->ReferL( headers );          
       
  1228     CleanupStack::Pop( headers );
       
  1229     
       
  1230     // Execution of the refer. Pass ownership of the arguments. Generates 
       
  1231     // event to the MMceReferObserver. New MceOutEvent is created and events 
       
  1232     // of that then through MMceEventObserver interface.
       
  1233     iSVPSession->StartTimerL( KSVPReferExpirationTime,
       
  1234             KSVPReferTimerExpired  );// Start refer timer
       
  1235     
       
  1236     SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL Out" )
       
  1237 	}
       
  1238 
       
  1239 // ---------------------------------------------------------------------------
       
  1240 // CSVPTransferStateContext::SetMceEvent
       
  1241 // ---------------------------------------------------------------------------
       
  1242 //
       
  1243 void CSVPTransferStateContext::SetMceEvent( CMceEvent* aEvent )
       
  1244     {
       
  1245     SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent In" )
       
  1246     
       
  1247     if ( iMceEvent != aEvent )
       
  1248         {
       
  1249         delete iMceEvent;
       
  1250         iMceEvent = aEvent;
       
  1251         SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Updated" )
       
  1252         }
       
  1253     
       
  1254     SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Out" )
       
  1255     }
       
  1256 
       
  1257 // ---------------------------------------------------------------------------
       
  1258 // CSVPTransferStateContext::MceEvent
       
  1259 // ---------------------------------------------------------------------------
       
  1260 //
       
  1261 CMceEvent* CSVPTransferStateContext::MceEvent()
       
  1262     {
       
  1263     return iMceEvent;
       
  1264     }
       
  1265 
       
  1266 // ---------------------------------------------------------------------------
       
  1267 // CSVPTransferStateContext::StopReferTimer
       
  1268 // ---------------------------------------------------------------------------
       
  1269 //
       
  1270 void CSVPTransferStateContext::StopReferTimer()
       
  1271     {
       
  1272     SVPDEBUG1( "CSVPTransferStateContext::StopReferTimer" )
       
  1273     
       
  1274     iSVPSession->StopTimer( KSVPReferTimerExpired );
       
  1275     }
       
  1276 
       
  1277 // ---------------------------------------------------------------------------
       
  1278 // CSVPTransferStateContext::SetupHeadersL
       
  1279 // ---------------------------------------------------------------------------
       
  1280 //
       
  1281 CDesC8Array* CSVPTransferStateContext::SetupHeadersL()
       
  1282     {
       
  1283     SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL In" )
       
  1284     
       
  1285     CDesC8ArrayFlat* headers = new( ELeave ) CDesC8ArrayFlat(
       
  1286             KSVPHeaderArrayGranularity );
       
  1287     CleanupStack::PushL( headers );
       
  1288     
       
  1289     // Set "referred by" value - that is this end of the session.
       
  1290     TBuf8<KSVPTempStringlength> tempRefBy;
       
  1291     tempRefBy.Append( KSVPReferredBy );
       
  1292     
       
  1293     if ( iSVPSession->IsMobileOriginated() )
       
  1294         {
       
  1295         TDesC8* fromHdr = iSVPSession->FromHeader();
       
  1296         if ( fromHdr )
       
  1297             {
       
  1298             TInt indexLeft = fromHdr->Find( KSVPLeftBracketMark );
       
  1299             TInt indexRight = fromHdr->Find( KSVPRightBracketMark );
       
  1300             SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight );
       
  1301 
       
  1302             tempRefBy.Append( fromHdr->Mid( indexLeft,
       
  1303                     indexRight - indexLeft + KSVPSingleBracketLength ) );
       
  1304             }
       
  1305         }
       
  1306     else
       
  1307         {
       
  1308         TDesC8* toHdr = iSVPSession->ToHeader();
       
  1309         if ( toHdr )
       
  1310             {
       
  1311             TInt indexLeft = toHdr->Find( KSVPLeftBracketMark );
       
  1312             TInt indexRight = toHdr->Find( KSVPRightBracketMark );
       
  1313             SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight )
       
  1314 
       
  1315             tempRefBy.Append( toHdr->Mid( indexLeft,
       
  1316                     indexRight - indexLeft + KSVPSingleBracketLength ) );
       
  1317             }
       
  1318         }
       
  1319     
       
  1320     headers->AppendL( tempRefBy );
       
  1321     CleanupStack::Pop( headers );
       
  1322     
       
  1323     SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL Out" )
       
  1324     return headers;
       
  1325     }
       
  1326 
       
  1327 // ---------------------------------------------------------------------------
       
  1328 // CSVPTransferStateContext::InitializeStateArrayL
       
  1329 // ---------------------------------------------------------------------------
       
  1330 //
       
  1331 void CSVPTransferStateContext::InitializeStateArrayL()
       
  1332     {
       
  1333     // Create the array of the transfer states.
       
  1334     iStates = new ( ELeave ) RPointerArray<CSVPTransferStateBase>
       
  1335             ( KSVPTransferStateArraySize );
       
  1336     
       
  1337     // Transfer state classes are created here:
       
  1338     // Idle state
       
  1339     CSVPTransferStateBase* state = CSVPTransferIdleState::NewLC();
       
  1340     User::LeaveIfError( iStates->Insert(
       
  1341             state, KSVPTransferIdleStateIndex ) );
       
  1342     CleanupStack::Pop( state );
       
  1343     
       
  1344     // Pending state
       
  1345     state = CSVPTransferPendingState::NewLC();
       
  1346     User::LeaveIfError( iStates->Insert(
       
  1347             state, KSVPTransferPendingStateIndex ) );
       
  1348     CleanupStack::Pop( state );
       
  1349     
       
  1350     // Accepted state
       
  1351     state = CSVPTransferAcceptedState::NewLC();
       
  1352     User::LeaveIfError( iStates->Insert(
       
  1353             state, KSVPTransferAcceptedStateIndex ) );
       
  1354     CleanupStack::Pop( state );
       
  1355     
       
  1356     // Terminating state
       
  1357     state = CSVPTransferTerminatingState::NewLC();
       
  1358     User::LeaveIfError( iStates->Insert(
       
  1359             state, KSVPTransferTerminatingStateIndex ) );
       
  1360     CleanupStack::Pop( state );
       
  1361     
       
  1362     // Terminated state
       
  1363     state = CSVPTransferTerminatedState::NewLC();
       
  1364     User::LeaveIfError( iStates->Insert(
       
  1365             state, KSVPTransferTerminatedStateIndex ) );
       
  1366     CleanupStack::Pop( state );
       
  1367     }
       
  1368 
       
  1369 // -----------------------------------------------------------------------------
       
  1370 // CSVPTransferStateContext::IsStateTransitionAccepted
       
  1371 // -----------------------------------------------------------------------------
       
  1372 //
       
  1373 TBool CSVPTransferStateContext::IsStateTransitionAccepted(
       
  1374         const TSVPTransferStateIndex aNewState )
       
  1375 	{
       
  1376 	TSVPTransferStateIndex current = CurrentState();
       
  1377 	
       
  1378     SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: current  = %d", current )
       
  1379     SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: newstate = %d", aNewState )
       
  1380     
       
  1381     switch( current )
       
  1382         {
       
  1383         case KErrNotFound:
       
  1384             {
       
  1385             // Only idle state can be the first one.
       
  1386             if ( KSVPTransferIdleStateIndex  == aNewState )
       
  1387                 {
       
  1388                 return ETrue;
       
  1389                 }
       
  1390             else
       
  1391                 {
       
  1392                 return EFalse;
       
  1393                 }
       
  1394             }
       
  1395         
       
  1396         case KSVPTransferIdleStateIndex:
       
  1397             {
       
  1398             if ( KSVPTransferPendingStateIndex == aNewState ||
       
  1399                  KSVPTransferTerminatingStateIndex == aNewState )
       
  1400                 {
       
  1401                 return ETrue;
       
  1402                 }
       
  1403             else
       
  1404                 {
       
  1405                 return EFalse;
       
  1406                 }
       
  1407             }
       
  1408         
       
  1409         case KSVPTransferPendingStateIndex:
       
  1410             {
       
  1411             if ( KSVPTransferAcceptedStateIndex == aNewState ||
       
  1412                  KSVPTransferTerminatingStateIndex == aNewState )
       
  1413                 {
       
  1414                 return ETrue;
       
  1415                 }
       
  1416             else
       
  1417                 {
       
  1418                 return EFalse;
       
  1419                 }
       
  1420             }
       
  1421         
       
  1422         case KSVPTransferAcceptedStateIndex:
       
  1423             {
       
  1424             // If in accepted state, new transition is valid (return true).
       
  1425             // No transition actually occurs because
       
  1426             // state "changes" from accepted to accepted.
       
  1427             // This ignores sequent icoming NOTIFY's after REFER has been sent.
       
  1428             if ( KSVPTransferTerminatingStateIndex == aNewState ||
       
  1429                     KSVPTransferAcceptedStateIndex == aNewState)
       
  1430                 {
       
  1431                 return ETrue;
       
  1432                 }
       
  1433             else
       
  1434                 {
       
  1435                 return EFalse;
       
  1436                 }
       
  1437             }
       
  1438         
       
  1439         case KSVPTransferTerminatingStateIndex:
       
  1440             {
       
  1441             // From terminating state, transition to terminated is accepted.
       
  1442             if ( KSVPTransferTerminatingStateIndex == aNewState ||
       
  1443                  KSVPTransferTerminatedStateIndex == aNewState )
       
  1444                 {
       
  1445                 return ETrue;
       
  1446                 }
       
  1447             else
       
  1448                 {
       
  1449                 return EFalse;
       
  1450                 }
       
  1451             }
       
  1452         
       
  1453         case KSVPTransferTerminatedStateIndex:
       
  1454             {
       
  1455             // From terminated state, transition to idle is accepted.
       
  1456             if ( KSVPTransferIdleStateIndex == aNewState )
       
  1457                 {
       
  1458                 return ETrue;
       
  1459                 }
       
  1460             else
       
  1461                 {
       
  1462                 return EFalse;
       
  1463                 }
       
  1464             }
       
  1465         
       
  1466         default:
       
  1467             {
       
  1468             // Should not come here, since all the states are handled
       
  1469             SVPDEBUG1( "CSVPTransferStateContext::IsStateTransitionAccepted - Error" )
       
  1470             return EFalse;
       
  1471             }
       
  1472         // No breaks in switch case due returns.  
       
  1473         }
       
  1474 	}
       
  1475