sipvoipprovider/svptransfer/src/svptransferstatecontext.cpp
changeset 0 a4daefaec16c
child 11 6134b5029079
equal deleted inserted replaced
-1:000000000000 0:a4daefaec16c
       
     1 /*
       
     2 * Copyright (c) 2006 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             TBuf8<KSVPTempStringlength> replacesString;
       
   280             replacesString.Append( KSVPReplacesColonTxt );
       
   281             // add IncomingReplaces
       
   282             replacesString.Append( IncomingReplaces() );
       
   283             // Finally add collected Replaces string to header
       
   284             aUserAgentHeaders->AppendL( replacesString );
       
   285             }
       
   286         
       
   287         if ( iIncomingReferredBy )
       
   288             {
       
   289             SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL: Add referredBy header" )
       
   290             TBuf8<KSVPTempStringlength> referredByString;
       
   291             referredByString.Append( KSVPReferredBy );
       
   292             // add IncomingReferredBy
       
   293             referredByString.Append( IncomingReferredBy() );
       
   294             // Finally add collected Referred-By string to header
       
   295             aUserAgentHeaders->AppendL( referredByString );
       
   296             }
       
   297         }
       
   298     
       
   299     // Update transfer target address according preferred securesetting.
       
   300     UpdateTransferTargetL( aSecureStatus );
       
   301     
       
   302     SVPDEBUG1( "CSVPTransferStateContext::SetTransferDataL Out" )
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------------------------
       
   306 // CSVPTransferStateContext::IsIncoming
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 TBool CSVPTransferStateContext::IsIncoming()
       
   310     {
       
   311     return ( NULL != iIncomingReferTo );
       
   312     }
       
   313 
       
   314 // ---------------------------------------------------------------------------
       
   315 // CSVPTransferStateContext::SetIncomingReferToL
       
   316 // ---------------------------------------------------------------------------
       
   317 //
       
   318 void CSVPTransferStateContext::SetIncomingReferToL( const TDesC8& aReferTo )
       
   319     {
       
   320     SVPDEBUG1("CSVPTransferStateContext::SetIncomingReferToL In" )
       
   321     
       
   322     ResetIncomingReferTo();
       
   323     
       
   324     // modify aReferTo
       
   325     HBufC8* referTo = CompleteReferToL( aReferTo );
       
   326     CleanupStack::PushL( referTo );
       
   327 
       
   328     // at this point referto must contains legal sip uri
       
   329     RemoveExtraParameters( referTo );
       
   330     
       
   331     // Check length - moSession construct limitation
       
   332     // sip: or sips: prefix will be added later, so 95 is maximum
       
   333     if ( referTo->Length() < ( KSVPMaxUriLength - KSVPSipPrefixLength ) )
       
   334         {
       
   335         // Copy and convert the "refer to" -parameter.
       
   336         iIncomingReferTo = HBufC::NewL( referTo->Length() );
       
   337         TPtr temp = iIncomingReferTo->Des();
       
   338         temp.Copy( *referTo );
       
   339         }
       
   340     else
       
   341         {
       
   342         SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL: referTo too long, Leave" )
       
   343         User::Leave( KErrArgument );
       
   344         }
       
   345     
       
   346     CleanupStack::PopAndDestroy( referTo );
       
   347     
       
   348    SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferToL lenght: %d",
       
   349             iIncomingReferTo->Length())
       
   350     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferToL Out" )
       
   351     }
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CSVPSessionBase::SetIncomingReferredByL
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 void CSVPTransferStateContext::SetIncomingReferredByL( const TDesC8& aReferredBy )
       
   358     {
       
   359     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL In" )
       
   360     
       
   361     ResetIncomingReferredBy();
       
   362     
       
   363     // modify aReferredBy
       
   364     HBufC8* referredBy = CompleteReferredByL( aReferredBy );
       
   365     CleanupStack::PushL( referredBy );
       
   366     
       
   367     // Copy and convert the "Referred By" -parameter.    
       
   368     iIncomingReferredBy = HBufC::NewL( referredBy->Length() );
       
   369     TPtr temp = iIncomingReferredBy->Des();
       
   370     temp.Copy( *referredBy );
       
   371     CleanupStack::PopAndDestroy( referredBy );
       
   372     
       
   373     SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReferredByL lenght: %d",
       
   374             iIncomingReferredBy->Length() )
       
   375     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReferredByL Out" )
       
   376     }    
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // CSVPTransferStateContext::SetIncomingReplacesL
       
   380 // ---------------------------------------------------------------------------
       
   381 //
       
   382 void CSVPTransferStateContext::SetIncomingReplacesL( const TDesC8& aString )
       
   383     { 
       
   384     SVPDEBUG1("CSVPTransferStateContext::SetIncomingReplacesL In" )
       
   385     
       
   386     ResetIncomingReplaces();
       
   387     
       
   388     // modify Replaces
       
   389     HBufC8* string = CompleteReplacesL( aString );
       
   390     CleanupStack::PushL( string );
       
   391     
       
   392     // Copy and convert the "Replaces" -parameter.    
       
   393     iIncomingReplaces = HBufC::NewL( string->Length() );
       
   394     TPtr temp = iIncomingReplaces->Des();
       
   395     temp.Copy( *string );
       
   396     CleanupStack::PopAndDestroy( string );
       
   397     
       
   398     SVPDEBUG2( "CSVPTransferStateContext::SetIncomingReplacesL lenght: %d",
       
   399             iIncomingReplaces->Length() )
       
   400     SVPDEBUG1( "CSVPTransferStateContext::SetIncomingReplacesL Out" )
       
   401     }
       
   402 
       
   403 // ---------------------------------------------------------------------------
       
   404 // CSVPTransferStateContext::CompleteReplacesL
       
   405 // ---------------------------------------------------------------------------
       
   406 //
       
   407 HBufC8* CSVPTransferStateContext::CompleteReplacesL( const TDesC8& aString )
       
   408     {
       
   409     SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL In" )
       
   410     
       
   411     // Copy the parameter to a new buffer.
       
   412     HBufC8* string = aString.AllocLC();
       
   413     // If "?Replaces=" found attended transfer case
       
   414     TInt position = CheckReplacesTxt( *string );
       
   415     SVPDEBUG2( "    CheckReplacesTxt returns = %d", position );
       
   416     
       
   417     if ( KErrNotFound != position )
       
   418         {
       
   419         TakeReplacesTxt( string, position );
       
   420         CleanupStack::Pop( 1 ); // string, ReAlloc possible
       
   421         CleanupStack::PushL( string );
       
   422         }
       
   423     
       
   424     // Check ">" and remove text after it if exists
       
   425     position = CheckRightBracket( *string );
       
   426     SVPDEBUG2("    CheckRightBracket returns = %d" , position )
       
   427     
       
   428     if ( KErrNotFound != position )
       
   429         {
       
   430         // ">" found
       
   431         CutStringFromPosition( string, position );
       
   432         CleanupStack::Pop( 1 ); // string, ReAlloc possible
       
   433         CleanupStack::PushL( string );
       
   434         }
       
   435     
       
   436     HBufC8* temp = EscapeUtils::EscapeDecodeL( *string );
       
   437     CleanupStack::PopAndDestroy( string );
       
   438     
       
   439     SVPDEBUG1( "CSVPTransferStateContext::CompleteReplacesL Out" )
       
   440     return temp;
       
   441     }
       
   442 
       
   443 // ---------------------------------------------------------------------------
       
   444 // CSVPTransferStateContext::CompleteReferToL
       
   445 // ---------------------------------------------------------------------------
       
   446 //
       
   447 HBufC8* CSVPTransferStateContext::CompleteReferToL( const TDesC8& aUri )
       
   448     {
       
   449     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL In" )
       
   450     
       
   451     // Copy the parameter to a new buffer.
       
   452     HBufC8* uri = aUri.AllocLC();
       
   453     
       
   454     // Check "<" and remove it and text before it if exists
       
   455     TInt position = CheckLeftBracket( *uri );
       
   456     
       
   457     if ( KErrNotFound != position )
       
   458         {
       
   459         RemoveLeftBracket( uri, position );
       
   460         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   461         CleanupStack::PushL( uri );
       
   462         }
       
   463     
       
   464     // Check ";user=phone" and remove if exists
       
   465     position = CheckUserEqualsPhone( *uri );
       
   466     
       
   467     if ( KErrNotFound != position )
       
   468         {
       
   469         // ";user=phone" found
       
   470         RemoveUserEqualsPhone( uri, position );
       
   471         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   472         CleanupStack::PushL( uri );
       
   473         }
       
   474     
       
   475     // Check ">" and remove text after it if exists
       
   476     position = CheckRightBracket( *uri );
       
   477     
       
   478     if ( KErrNotFound != position )
       
   479         {
       
   480         // ">" found
       
   481         CutStringFromPosition( uri, position );
       
   482         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   483         CleanupStack::PushL( uri );
       
   484         }
       
   485     
       
   486     // Check "KSVPQuesReplacesTxt" and remove text after it if exists
       
   487     // If it is found -> attended transfer case
       
   488     position = CheckReplacesTxt( *uri );
       
   489     
       
   490     if ( KErrNotFound != position )
       
   491         {
       
   492         // Found -> attended case.
       
   493         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= found -> attended transfer" )
       
   494         SetAttended( ETrue );
       
   495         SetIncomingReplacesL( aUri );
       
   496         CutStringFromPosition( uri, position );
       
   497         }
       
   498     else
       
   499         {
       
   500         // Not found -> unattended case.
       
   501         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL ?Replaces= not found -> unattended transfer" )
       
   502         SetAttended( EFalse );
       
   503         }
       
   504 
       
   505     // Check "?X-Sipx-Authidentity=" and remove text after it if exists
       
   506     position = CheckAuthidentity( *uri );
       
   507 
       
   508     if ( KErrNotFound != position )
       
   509         {
       
   510         // "?X-Sipx-Authidentity=" found
       
   511         CutStringFromPosition( uri, position );
       
   512         CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   513         CleanupStack::PushL( uri );
       
   514         }
       
   515 
       
   516     // Check "sip:" and remove it if exists
       
   517     if ( KErrNone == uri->Find( KSVPSipPrefix ) )
       
   518         {
       
   519         // sip: is in the beginning of the string
       
   520         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sip:" )
       
   521         uri->Des().Delete( 0, KSVPSipPrefixLength );
       
   522         }
       
   523 
       
   524     // Check "sips:" and remove it if exists
       
   525     if ( KErrNone == uri->Find( KSVPSipsPrefix ) )
       
   526         {
       
   527         // sips: is in the beginning of the string
       
   528         SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL remove sips:" )
       
   529         uri->Des().Delete( 0, KSVPSipsPrefixLength );
       
   530         }
       
   531 
       
   532     // Check ":" and remove text after it if exists,
       
   533     // some server might add this after transfer target address
       
   534     position = uri->Find( KSVPCln );
       
   535 
       
   536     if ( KErrNotFound != position )
       
   537         {
       
   538         // ":" found
       
   539         SVPDEBUG2( "CSVPTransferStateContext::CompleteReferToL remove text after %d ", position )
       
   540         uri->Des().Delete( position, uri->Length() - position );
       
   541         }
       
   542 
       
   543     CleanupStack::Pop( 1 ); // uri, ReAlloc possible
       
   544     
       
   545     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferToL Out" )
       
   546     return uri;
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // CSVPTransferStateContext::CompleteReferredByL
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 HBufC8* CSVPTransferStateContext::CompleteReferredByL(
       
   554         const TDesC8& aReferredBy )
       
   555     {
       
   556     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL In" )
       
   557     
       
   558     // Copy the parameter to a new buffer.
       
   559     HBufC8* referredBy = aReferredBy.AllocLC();
       
   560     
       
   561     // Check "Referred-By:" and remove it
       
   562     TInt position = CheckReferredByTxt( *referredBy );
       
   563     
       
   564     if ( KErrNotFound != position )
       
   565         {
       
   566         // "Referred-By:" found.
       
   567         RemoveReferredByTxt( referredBy, position );
       
   568         }
       
   569     
       
   570     CleanupStack::Pop( 1 ); // referredBy, ReAlloc possible
       
   571     
       
   572     SVPDEBUG1( "CSVPTransferStateContext::CompleteReferredByL Out" )
       
   573     return referredBy;
       
   574     }
       
   575 
       
   576 // ---------------------------------------------------------------------------
       
   577 // CSVPTransferStateContext::CheckUserEqualsPhone
       
   578 // ---------------------------------------------------------------------------
       
   579 //
       
   580 TInt CSVPTransferStateContext::CheckUserEqualsPhone( const TDesC8& aUri ) const
       
   581     {
       
   582     SVPDEBUG1( "CSVPTransferStateContext::CheckUserEqualsPhone" )
       
   583     
       
   584     return ( aUri.FindF( KSVPUserEqualsPhone ) );
       
   585     }
       
   586 
       
   587 // ---------------------------------------------------------------------------
       
   588 // CSVPTransferStateContext::RemoveUserEqualsPhone
       
   589 // ---------------------------------------------------------------------------
       
   590 //
       
   591 void CSVPTransferStateContext::RemoveUserEqualsPhone(
       
   592         HBufC8*& aUri, TInt aPosition ) const
       
   593     {
       
   594     SVPDEBUG2( "CSVPTransferStateContext::RemoveUserEqualsPhone posit = %d", aPosition )
       
   595     
       
   596     aUri->Des().Delete( aPosition, KSVPUserEqualsPhoneLenght );
       
   597     }
       
   598 
       
   599 // ---------------------------------------------------------------------------
       
   600 // CSVPTransferStateContext::RemoveExtraParameters
       
   601 // ---------------------------------------------------------------------------
       
   602 //
       
   603 void CSVPTransferStateContext::RemoveExtraParameters( HBufC8*& aUri ) const 
       
   604     {
       
   605     SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters In" )
       
   606     
       
   607     // remove all extra parameters from given address
       
   608     TInt index = aUri->Locate( KSVPSemiColonMark );
       
   609     TInt bracketLocation = KErrNotFound;
       
   610     
       
   611     SVPDEBUG3( "CSVPTransferStateContext::RemoveExtraParameters index = %d, length = %d",
       
   612         index, aUri->Length() )
       
   613     
       
   614     if ( KErrNotFound != index )
       
   615         {
       
   616         // Delete ";" and text after it
       
   617         aUri->Des().Delete( index, aUri->Length() );
       
   618         }
       
   619     
       
   620     // Check "<" and remove it and text before it if exists
       
   621     bracketLocation = CheckLeftBracket( *aUri );
       
   622     
       
   623     if ( KErrNotFound != bracketLocation )
       
   624         {
       
   625         RemoveLeftBracket( aUri, bracketLocation );
       
   626         }
       
   627     
       
   628     // Check ">" and remove text after it if exists
       
   629     bracketLocation = CheckRightBracket( *aUri );
       
   630     
       
   631     if ( KErrNotFound != bracketLocation )
       
   632         {
       
   633         CutStringFromPosition( aUri, bracketLocation );
       
   634         }
       
   635     
       
   636     SVPDEBUG1( "CSVPTransferStateContext::RemoveExtraParameters Out" )
       
   637     }
       
   638 
       
   639 // ---------------------------------------------------------------------------
       
   640 // CSVPTransferStateContext::CheckReplacesTxt
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 TInt CSVPTransferStateContext::CheckReplacesTxt( const TDesC8& aUri ) const
       
   644     {
       
   645     SVPDEBUG1( "CSVPTransferStateContext::CheckReplacesTxt" )
       
   646     
       
   647     return ( aUri.FindF( KSVPQuesReplacesTxt ) );
       
   648     }
       
   649 
       
   650 // ---------------------------------------------------------------------------
       
   651 // CSVPTransferStateContext::CutStringFromPosition
       
   652 // ---------------------------------------------------------------------------
       
   653 //
       
   654 void CSVPTransferStateContext::CutStringFromPosition(
       
   655         HBufC8*& aUri, TInt aPosition ) const
       
   656     {
       
   657     SVPDEBUG2( "CSVPTransferStateContext::CutStringFromPosition posit = %d", aPosition )
       
   658     aUri->Des().Delete( aPosition, aUri->Length() - aPosition );
       
   659     }
       
   660 
       
   661 // ---------------------------------------------------------------------------
       
   662 // CSVPTransferStateContext::CheckReferredByTxt
       
   663 // ---------------------------------------------------------------------------
       
   664 //
       
   665 TInt CSVPTransferStateContext::CheckReferredByTxt(
       
   666         const TDesC8& aReferredBy ) const
       
   667     {
       
   668     SVPDEBUG1( "CSVPTransferStateContext::CheckReferredByTxt" )
       
   669     
       
   670     return ( aReferredBy.FindF( KSVPReferredBy ) );
       
   671     }
       
   672 
       
   673 // ---------------------------------------------------------------------------
       
   674 // CSVPTransferStateContext::RemoveReferredByTxt
       
   675 // ---------------------------------------------------------------------------
       
   676 //
       
   677 void CSVPTransferStateContext::RemoveReferredByTxt(
       
   678         HBufC8*& aReferredBy, TInt aPosition ) const
       
   679     {
       
   680     SVPDEBUG2( "CSVPTransferStateContext::RemoveReferredByTxt posit = %d", aPosition )
       
   681     
       
   682     aReferredBy->Des().Delete( aPosition, KSVPReferredByLength + 1 );
       
   683     }
       
   684 
       
   685 // ---------------------------------------------------------------------------
       
   686 // CSVPTransferStateContext::TakeReplacesTxt
       
   687 // ---------------------------------------------------------------------------
       
   688 //
       
   689 void CSVPTransferStateContext::TakeReplacesTxt(
       
   690         HBufC8*& aString, TInt aPosition ) const
       
   691     {
       
   692     SVPDEBUG2( "CSVPTransferStateContext::TakeReplacesTxt posit = %d", aPosition )
       
   693     
       
   694     aString->Des().Delete( 0, aPosition + KSVPQuesReplacesTxtLength );
       
   695     }
       
   696 
       
   697 // ---------------------------------------------------------------------------
       
   698 // CSVPTransferStateContext::CheckLeftBracket
       
   699 // ---------------------------------------------------------------------------
       
   700 //
       
   701 TInt CSVPTransferStateContext::CheckLeftBracket( const TDesC8& aUri ) const
       
   702     {
       
   703     SVPDEBUG1( "CSVPTransferStateContext::CheckLeftBracket" )
       
   704     
       
   705     // Return position of "<" or KErrNotFound
       
   706     return ( aUri.Find( KSVPLeftBracketMark ) );
       
   707     }
       
   708 
       
   709 // ---------------------------------------------------------------------------
       
   710 // CSVPTransferStateContext::RemoveLeftBracket
       
   711 // ---------------------------------------------------------------------------
       
   712 //
       
   713 void CSVPTransferStateContext::RemoveLeftBracket(
       
   714         HBufC8*& aUri, TInt aPosition ) const
       
   715     {
       
   716     SVPDEBUG2( "CSVPTransferStateContext::RemoveLeftBracket posit = %d", aPosition )
       
   717     
       
   718     aUri->Des().Delete( 0, aPosition + KSVPSingleBracketLength );
       
   719     }
       
   720 
       
   721 // ---------------------------------------------------------------------------
       
   722 // CSVPTransferStateContext::CheckRightBracket
       
   723 // ---------------------------------------------------------------------------
       
   724 //
       
   725 TInt CSVPTransferStateContext::CheckRightBracket( const TDesC8& aUri ) const
       
   726     {
       
   727     SVPDEBUG1( "CSVPTransferStateContext::CheckRightBracket" )
       
   728     
       
   729     return ( aUri.Find( KSVPRightBracketMark ) );
       
   730     }
       
   731 
       
   732 // ---------------------------------------------------------------------------
       
   733 // CSVPTransferStateContext::CheckAuthidentity  
       
   734 // ---------------------------------------------------------------------------
       
   735 //
       
   736 TInt CSVPTransferStateContext::CheckAuthidentity( const TDesC8& aUri ) const
       
   737     {
       
   738     SVPDEBUG1( "CSVPTransferStateContext::CheckAuthidentity" )
       
   739     return ( aUri.Find( KSVPAuthidentity ) );
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------------------------
       
   743 // CSVPTransferStateContext::IncomingReferTo
       
   744 // ---------------------------------------------------------------------------
       
   745 //
       
   746 const TDesC& CSVPTransferStateContext::IncomingReferTo()
       
   747     {
       
   748     SVPDEBUG1( "CSVPTransferStateContext::IncomingReferTo" )
       
   749     
       
   750     return *iIncomingReferTo;
       
   751     }
       
   752 
       
   753 // ---------------------------------------------------------------------------
       
   754 // CSVPTransferStateContext::UpdateTransferTargetL
       
   755 // ---------------------------------------------------------------------------
       
   756 //
       
   757 void CSVPTransferStateContext::UpdateTransferTargetL( TInt aSecureStatus )
       
   758     {
       
   759     SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL In" )
       
   760     
       
   761     if ( iIncomingReferTo )
       
   762         {
       
   763         if ( KSVPStatusNonSecure == aSecureStatus )
       
   764             {
       
   765             SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIP uri" )
       
   766             
       
   767             // Check "sips:" and remove it if exists
       
   768             if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
       
   769                 {
       
   770                 // sips: is in the beginning of the string, position 0
       
   771                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sips:" )
       
   772                 iIncomingReferTo->Des().Delete( 0, KSVPSipsPrefixLength );
       
   773                 }
       
   774             
       
   775             // Add "sip:" prefix in the beginning of the string, if it's missing.
       
   776             if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
       
   777                 {
       
   778                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sip:" )
       
   779                 iIncomingReferTo = iIncomingReferTo->ReAllocL(
       
   780                         iIncomingReferTo->Length() + KSVPSipPrefixLength );
       
   781                 iIncomingReferTo->Des().Insert( 0, KSVPSipPrefix2 );
       
   782                 }
       
   783             }
       
   784         else
       
   785             {
       
   786             SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add SIPS" )
       
   787             
       
   788             // Check "sip:" and remove it if exists
       
   789             if ( KErrNone == iIncomingReferTo->Des().FindF( KSVPSipPrefix2 ) )
       
   790                 {
       
   791                 // sip: is in the beginning of the string
       
   792                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL remove sip:" )
       
   793                 iIncomingReferTo->Des().Delete( 0, KSVPSipPrefixLength );
       
   794                 }
       
   795             
       
   796             // Add "sips:" prefix in the beginning of the string, if it's missing.
       
   797             if ( KErrNotFound == iIncomingReferTo->Des().FindF( KSVPSipsPrefix2 ) )
       
   798                 {
       
   799                 SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL add sips:" )
       
   800                 iIncomingReferTo = iIncomingReferTo->ReAllocL(
       
   801                         iIncomingReferTo->Length() + KSVPSipsPrefixLength );
       
   802                 iIncomingReferTo->Des().Insert( 0, KSVPSipsPrefix2 );
       
   803                 }
       
   804             }
       
   805         }
       
   806     else
       
   807         {
       
   808         SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL IncomingReferTo Not OK" )
       
   809         }
       
   810     
       
   811     SVPDEBUG1( "CSVPTransferStateContext::UpdateTransferTargetL Out" )
       
   812     }
       
   813 
       
   814 // ---------------------------------------------------------------------------
       
   815 // CSVPTransferStateContext::ResetIncomingReferTo
       
   816 // ---------------------------------------------------------------------------
       
   817 //
       
   818 void CSVPTransferStateContext::ResetIncomingReferTo()
       
   819     {
       
   820     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferTo" )    
       
   821     
       
   822     if ( iIncomingReferTo )
       
   823         {
       
   824         delete iIncomingReferTo;
       
   825         iIncomingReferTo = NULL;
       
   826         }
       
   827     }
       
   828 
       
   829 // ---------------------------------------------------------------------------
       
   830 // CSVPTransferStateContext::ResetIncomingReferredBy
       
   831 // ---------------------------------------------------------------------------
       
   832 //
       
   833 void CSVPTransferStateContext::ResetIncomingReferredBy()
       
   834     {
       
   835     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReferredBy" )
       
   836     
       
   837     if ( iIncomingReferredBy )
       
   838         {
       
   839         delete iIncomingReferredBy;
       
   840         iIncomingReferredBy = NULL;
       
   841         }
       
   842     }
       
   843 
       
   844 // ---------------------------------------------------------------------------
       
   845 // CSVPTransferStateContext::IncomingReferredBy
       
   846 // ---------------------------------------------------------------------------
       
   847 //
       
   848 const TDesC& CSVPTransferStateContext::IncomingReferredBy()
       
   849     {
       
   850     SVPDEBUG1( "CSVPTransferStateContext::IncomingReferredBy" )
       
   851     
       
   852     return *iIncomingReferredBy;
       
   853     }
       
   854 
       
   855 // ---------------------------------------------------------------------------
       
   856 // CSVPTransferStateContext::IncomingReplaces
       
   857 // ---------------------------------------------------------------------------
       
   858 //
       
   859 const TDesC& CSVPTransferStateContext::IncomingReplaces()
       
   860     {
       
   861     SVPDEBUG1( "CSVPTransferStateContext::IncomingReplaces" )
       
   862     
       
   863     return *iIncomingReplaces;
       
   864     }
       
   865 
       
   866 // ---------------------------------------------------------------------------
       
   867 // CSVPTransferStateContext::ResetIncomingReplaces
       
   868 // ---------------------------------------------------------------------------
       
   869 //
       
   870 void CSVPTransferStateContext::ResetIncomingReplaces()
       
   871     {
       
   872     SVPDEBUG1( "CSVPTransferStateContext::ResetIncomingReplaces" )
       
   873     
       
   874     if ( iIncomingReplaces )
       
   875         {
       
   876         delete iIncomingReplaces;
       
   877         iIncomingReplaces = NULL;
       
   878         }
       
   879     }
       
   880 
       
   881 // ---------------------------------------------------------------------------
       
   882 // CSVPTransferStateContext::SetTransferParmsL
       
   883 // ---------------------------------------------------------------------------
       
   884 //
       
   885 void CSVPTransferStateContext::SetTransferParmsL(
       
   886         CSVPSessionBase* aTargetSession, const TDesC& aTarget,
       
   887         const TBool aAttendedTransfer )
       
   888     {
       
   889     SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL In" )
       
   890     
       
   891     // No target session as default. 
       
   892     iTargetSession = NULL;
       
   893     
       
   894     // Delete possible old refer 
       
   895     delete iMceRefer;
       
   896     iMceRefer = NULL;
       
   897     
       
   898     // Set attended/unattended transfer
       
   899     SetAttended( aAttendedTransfer );
       
   900     
       
   901     // Create mce out refer using given target parameter or call
       
   902     if ( aTarget.Length() > 0 )
       
   903         {
       
   904         CreateMceOutReferL( aTarget );
       
   905         }
       
   906     else
       
   907         {
       
   908         CreateMceOutReferL( aTargetSession );
       
   909         }
       
   910     
       
   911     SVPDEBUG1( "CSVPTransferStateContext::SetTransferParmsL Out" )
       
   912     }
       
   913 
       
   914 // ---------------------------------------------------------------------------
       
   915 // CSVPTransferStateContext::CreateMceOutReferL
       
   916 // ---------------------------------------------------------------------------
       
   917 //
       
   918 void CSVPTransferStateContext::CreateMceOutReferL( const TDesC& aTarget )
       
   919     {
       
   920     // Create mce out refer using target string (unattended).   
       
   921     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) In" )
       
   922     
       
   923     // Copy 'refer to' argument
       
   924     HBufC8* target = HBufC8::NewLC( aTarget.Length() );
       
   925     target->Des().Copy( aTarget );
       
   926     
       
   927     // Parse target with uri parser, use session recipient as domain source 
       
   928     CSVPUriParser* uriParser = CSVPUriParser::NewLC();
       
   929     HBufC8* referto = NULL;
       
   930     RPointerArray< CRCSEProfileEntry > entryArray;
       
   931     CleanupResetAndDestroy< RPointerArray<CRCSEProfileEntry> >::PushL( entryArray );
       
   932     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC();
       
   933     
       
   934     // Get VoIP profile by service id
       
   935     reg->FindByServiceIdL( iSVPSession->Parameters().ServiceId(), entryArray );
       
   936     __ASSERT_ALWAYS( entryArray.Count(), User::Leave( KErrArgument ) );
       
   937     CRCSEProfileEntry* entry = entryArray[0];
       
   938     uriParser->SetUserEqualsPhoneRequiredL(
       
   939             CRCSEProfileEntry::EOn == entry->iUserPhoneUriParameter );
       
   940     
       
   941     CleanupStack::PopAndDestroy( reg );
       
   942     CleanupStack::PopAndDestroy( &entryArray );
       
   943 
       
   944     HBufC8* recipient = NULL;
       
   945     const CMceSession& session = iSVPSession->Session();
       
   946     __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
       
   947 
       
   948     if ( iSVPSession->IsMobileOriginated() ) 
       
   949         {
       
   950         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), MO case" )
       
   951         const TDesC8& recip = session.Recipient();
       
   952         __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
       
   953         recipient = HBufC8::NewLC( recip.Length() );
       
   954         recipient->Des().Copy( recip );
       
   955         }
       
   956     else
       
   957         {
       
   958         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget), MT case" )
       
   959         const TDesC8& orig = session.Originator();
       
   960         __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
       
   961         recipient = HBufC8::NewLC( orig.Length() );
       
   962         recipient->Des().Copy( orig );    
       
   963         }
       
   964 
       
   965     // remove all extra parameters from recipient address
       
   966     RemoveExtraParameters( recipient );
       
   967     
       
   968     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) recipient->Length() = %d",
       
   969                recipient->Length() )
       
   970     
       
   971     if ( iSVPSession->SecureMandatory() || iSVPSession->SecurePreferred() )
       
   972         {
       
   973         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIPS URI..." )
       
   974         referto = uriParser->CompleteSecureSipUriL( *target, *recipient );
       
   975         }
       
   976     else
       
   977         {
       
   978         SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) SIP URI..." )
       
   979         referto = uriParser->CompleteSipUriL( *target, *recipient );
       
   980         }
       
   981     
       
   982     CleanupStack::PushL( referto );
       
   983     
       
   984     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 1 referto->Length() = %d",
       
   985                referto->Length() )
       
   986     
       
   987     // remove all extra parameters from referto
       
   988     RemoveExtraParameters( referto );
       
   989 
       
   990     SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) 2 referto->Length() = %d",
       
   991                referto->Length() )
       
   992     
       
   993     // Create the refer
       
   994     delete iMceRefer;
       
   995     iMceRefer = NULL;
       
   996     iMceRefer = CMceOutRefer::NewL( *iMceSession, *referto, CMceRefer::ENoSuppression );
       
   997     CleanupStack::PopAndDestroy( referto );
       
   998     
       
   999     CleanupStack::PopAndDestroy( recipient );
       
  1000     CleanupStack::PopAndDestroy( uriParser );
       
  1001     CleanupStack::PopAndDestroy( target );
       
  1002     
       
  1003     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTarget) Out" )
       
  1004 	}
       
  1005 
       
  1006 // ---------------------------------------------------------------------------
       
  1007 // CSVPTransferStateContext::CreateMceOutReferL
       
  1008 // ---------------------------------------------------------------------------
       
  1009 //
       
  1010 void CSVPTransferStateContext::CreateMceOutReferL( CSVPSessionBase* aTargetSession )
       
  1011     {
       
  1012     // Create mce out refer using session (attended).   
       
  1013     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) In" )    
       
  1014     
       
  1015     // Store target session 
       
  1016     iTargetSession = aTargetSession;
       
  1017     
       
  1018     // Construct the refer-to string
       
  1019     HBufC8* referto = HBufC8::NewLC( KSVPTempStringlength );
       
  1020     TPtr8 refptr = referto->Des();
       
  1021     
       
  1022     if ( iTargetSession )
       
  1023         {
       
  1024         // Set refer-to for the attended transfer using the target session,
       
  1025         // that can not be the same as the owner session of the 
       
  1026         // transfer controller.
       
  1027         if ( iSVPSession != iTargetSession )
       
  1028             {
       
  1029             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) TargetSession = 0x%x", &iTargetSession )
       
  1030             
       
  1031             HBufC8* recipient = NULL;
       
  1032             const CMceSession& session = iTargetSession->Session();
       
  1033             __ASSERT_ALWAYS( &session, User::Leave( KErrArgument ) );
       
  1034             
       
  1035             if ( iTargetSession->IsMobileOriginated() ) 
       
  1036                 {
       
  1037                 const TDesC8& recip = session.Recipient();
       
  1038                 __ASSERT_ALWAYS( &recip, User::Leave( KErrArgument ) );
       
  1039                 recipient = HBufC8::NewLC( recip.Length() );
       
  1040                 recipient->Des().Copy( recip );
       
  1041                 }
       
  1042             else
       
  1043                 {
       
  1044                 const TDesC8& orig = session.Originator();
       
  1045                 __ASSERT_ALWAYS( &orig, User::Leave( KErrArgument ) );
       
  1046                 recipient = HBufC8::NewLC( orig.Length() );
       
  1047                 recipient->Des().Copy( orig );    
       
  1048                 }
       
  1049             
       
  1050             // remove all extra parameters from recipient address
       
  1051             RemoveExtraParameters( recipient );
       
  1052             
       
  1053             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) recipient->Length() = %d",
       
  1054                recipient->Length() )
       
  1055             
       
  1056             // Set the refer-to address (recipient)
       
  1057             refptr.Append( recipient->Des() );
       
  1058             CleanupStack::PopAndDestroy( recipient );
       
  1059             
       
  1060             // Gather up the rest of the refer-to data (replaces etc.)  
       
  1061             // from the target session (sessionbase) member variables.
       
  1062             TBuf8<KSVPTempStringlength> tmp( KNullDesC8 );
       
  1063             tmp.Append( KSVPQuesReplacesTxt ); // Set CallId
       
  1064             
       
  1065             if ( iTargetSession->CallId() )
       
  1066                 {
       
  1067                 // Set "replaces" callid string starting from next char 
       
  1068                 // the of KSVPCallId_replaces -text
       
  1069                 TDesC8* callid = iTargetSession->CallId();
       
  1070                 TInt index = callid->Find( KSVPCallId_replaces );
       
  1071                 
       
  1072                 if ( KErrNotFound != index )
       
  1073                     {
       
  1074                     // Check and encode the possible @ char of the callid 
       
  1075                     // to "%40" format. This kind of callid e.g. in Cisco 7960.
       
  1076                     TInt index2 = callid->Find( KSVPAt );
       
  1077                     
       
  1078                     if ( KErrNotFound != index2 )
       
  1079                 	    {
       
  1080                 	    HBufC8* tmpCallId = HBufC8::NewLC( callid->Length() );
       
  1081                 	    tmpCallId->Des().Append( callid->Mid( index +
       
  1082                 	            KSVPCallId_replaces().Length() ) );
       
  1083                 	    CSVPUriParser::EscapeEncodeSipUriL( tmpCallId,
       
  1084                                 EscapeUtils::EEscapeUrlEncoded );
       
  1085                         tmp.Append( *tmpCallId );
       
  1086                         CleanupStack::Pop( 1 ); // tmpCallId, ReAlloc possible
       
  1087                         delete tmpCallId;
       
  1088                         }
       
  1089                     else
       
  1090                         {
       
  1091                         // Normal copy from the correct position
       
  1092                         tmp.Append( callid->Mid( index +
       
  1093                                 KSVPCallId_replaces().Length() ) );
       
  1094                         }
       
  1095                     }
       
  1096                 }
       
  1097             else
       
  1098                 {
       
  1099                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing CallId %i", KSVPErrTransferReferTo )
       
  1100                 User::Leave( KSVPErrTransferReferTo );
       
  1101                 }
       
  1102             
       
  1103             // To-header                    
       
  1104             if ( iTargetSession->ToHeader() )
       
  1105                 {
       
  1106                 tmp.Append( KSVPTo_tag );
       
  1107                 
       
  1108                 // Set "to" tag string starting from next char 
       
  1109                 // of the KSVPTo_tag_replaces -text
       
  1110                 TDesC8* toHdr = iTargetSession->ToHeader();
       
  1111                 TInt index = toHdr->Find( KSVP_tag );
       
  1112                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) toHdr index = %d", index )
       
  1113                 
       
  1114                 if ( KErrNotFound != index )
       
  1115                     {
       
  1116                     tmp.Append( toHdr->Mid( index + KSVPTagLength ) );
       
  1117                     }
       
  1118                 }
       
  1119             else
       
  1120                 {
       
  1121                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing ToHeader %i", KSVPErrTransferReferTo )        
       
  1122                 User::Leave( KSVPErrTransferReferTo );
       
  1123                 }
       
  1124             
       
  1125             // From-header
       
  1126             if ( iTargetSession->FromHeader() )
       
  1127                 {                    
       
  1128                 tmp.Append( KSVPFrom_tag );                    
       
  1129                 
       
  1130                 // Set "from" tag string starting from next char of 
       
  1131                 // the KSVPTo_tag_replaces -text
       
  1132                 TDesC8* fromHdr = iTargetSession->FromHeader();
       
  1133                 TInt index = fromHdr->Find( KSVP_tag );
       
  1134                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) fromHdr index = %d", index )
       
  1135                 
       
  1136                 if ( KErrNotFound != index )
       
  1137                     {
       
  1138                     tmp.Append( fromHdr->Mid( index + KSVPTagLength ) );
       
  1139                     }
       
  1140                 }
       
  1141             else
       
  1142                 {
       
  1143                 SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - missing FromHeader %i", KSVPErrTransferReferTo )
       
  1144                 User::Leave( KSVPErrTransferReferTo );
       
  1145                 }
       
  1146             
       
  1147             refptr.Append( tmp );
       
  1148             } // if ( iSVPSession != iTargetSession )
       
  1149         else
       
  1150             {
       
  1151             SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - the same target session %i", KSVPErrTransferReferTo )
       
  1152             User::Leave( KSVPErrTransferReferTo );
       
  1153             }
       
  1154         
       
  1155         // Create the refer
       
  1156         iMceRefer = CMceOutRefer::NewL( *iMceSession,
       
  1157                 *referto, CMceRefer::ENoSuppression );
       
  1158         } // if (iTargetSession)
       
  1159     else
       
  1160         {
       
  1161         SVPDEBUG2( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) error - no target session %i", KSVPErrTransferReferTo )        
       
  1162         User::Leave( KSVPErrTransferReferTo );
       
  1163         }
       
  1164     
       
  1165     CleanupStack::PopAndDestroy( referto );    	
       
  1166     
       
  1167     SVPDEBUG1( "CSVPTransferStateContext::CreateMceOutReferL(aTargetSession) Out" )        
       
  1168 	}
       
  1169 
       
  1170 // ---------------------------------------------------------------------------
       
  1171 // CSVPTransferStateContext::ExecuteReferL
       
  1172 // ---------------------------------------------------------------------------
       
  1173 //
       
  1174 void CSVPTransferStateContext::ExecuteReferL()
       
  1175     {
       
  1176     SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL In" )
       
  1177     
       
  1178     delete iMceEvent;
       
  1179     iMceEvent = NULL;
       
  1180     
       
  1181     // Create headers for refer call.
       
  1182     CDesC8Array* headers = SetupHeadersL();
       
  1183     CleanupStack::PushL( headers );
       
  1184     
       
  1185     // Refer with headers, passes ownership.
       
  1186     iMceEvent = static_cast< CMceOutRefer* >(MceRefer())->ReferL( headers );          
       
  1187     CleanupStack::Pop( headers );
       
  1188     
       
  1189     // Execution of the refer. Pass ownership of the arguments. Generates 
       
  1190     // event to the MMceReferObserver. New MceOutEvent is created and events 
       
  1191     // of that then through MMceEventObserver interface.
       
  1192     iSVPSession->StartTimerL( KSVPReferExpirationTime,
       
  1193             KSVPReferTimerExpired  );// Start refer timer
       
  1194     
       
  1195     SVPDEBUG1( "CSVPTransferStateContext::ExecuteReferL Out" )
       
  1196 	}
       
  1197 
       
  1198 // ---------------------------------------------------------------------------
       
  1199 // CSVPTransferStateContext::SetMceEvent
       
  1200 // ---------------------------------------------------------------------------
       
  1201 //
       
  1202 void CSVPTransferStateContext::SetMceEvent( CMceEvent* aEvent )
       
  1203     {
       
  1204     SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent In" )
       
  1205     
       
  1206     if ( iMceEvent != aEvent )
       
  1207         {
       
  1208         delete iMceEvent;
       
  1209         iMceEvent = aEvent;
       
  1210         SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Updated" )
       
  1211         }
       
  1212     
       
  1213     SVPDEBUG1( "CSVPTransferStateContext::SetMceEvent Out" )
       
  1214     }
       
  1215 
       
  1216 // ---------------------------------------------------------------------------
       
  1217 // CSVPTransferStateContext::MceEvent
       
  1218 // ---------------------------------------------------------------------------
       
  1219 //
       
  1220 CMceEvent* CSVPTransferStateContext::MceEvent()
       
  1221     {
       
  1222     return iMceEvent;
       
  1223     }
       
  1224 
       
  1225 // ---------------------------------------------------------------------------
       
  1226 // CSVPTransferStateContext::StopReferTimer
       
  1227 // ---------------------------------------------------------------------------
       
  1228 //
       
  1229 void CSVPTransferStateContext::StopReferTimer()
       
  1230     {
       
  1231     SVPDEBUG1( "CSVPTransferStateContext::StopReferTimer" )
       
  1232     
       
  1233     iSVPSession->StopTimer( KSVPReferTimerExpired );
       
  1234     }
       
  1235 
       
  1236 // ---------------------------------------------------------------------------
       
  1237 // CSVPTransferStateContext::SetupHeadersL
       
  1238 // ---------------------------------------------------------------------------
       
  1239 //
       
  1240 CDesC8Array* CSVPTransferStateContext::SetupHeadersL()
       
  1241     {
       
  1242     SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL In" )
       
  1243     
       
  1244     CDesC8ArrayFlat* headers = new( ELeave ) CDesC8ArrayFlat(
       
  1245             KSVPHeaderArrayGranularity );
       
  1246     CleanupStack::PushL( headers );
       
  1247     
       
  1248     // Set "referred by" value - that is this end of the session.
       
  1249     TBuf8<KSVPTempStringlength> tempRefBy;
       
  1250     tempRefBy.Append( KSVPReferredBy );
       
  1251     
       
  1252     if ( iSVPSession->IsMobileOriginated() )
       
  1253         {
       
  1254         TDesC8* fromHdr = iSVPSession->FromHeader();
       
  1255         if ( fromHdr )
       
  1256             {
       
  1257             TInt indexLeft = fromHdr->Find( KSVPLeftBracketMark );
       
  1258             TInt indexRight = fromHdr->Find( KSVPRightBracketMark );
       
  1259             SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight );
       
  1260 
       
  1261             tempRefBy.Append( fromHdr->Mid( indexLeft,
       
  1262                     indexRight - indexLeft + KSVPSingleBracketLength ) );
       
  1263             }
       
  1264         }
       
  1265     else
       
  1266         {
       
  1267         TDesC8* toHdr = iSVPSession->ToHeader();
       
  1268         if ( toHdr )
       
  1269             {
       
  1270             TInt indexLeft = toHdr->Find( KSVPLeftBracketMark );
       
  1271             TInt indexRight = toHdr->Find( KSVPRightBracketMark );
       
  1272             SVPDEBUG3( "CSVPTransferStateContext::SetupHeadersL: indexLeft = %d, indexRight =  %d", indexLeft, indexRight )
       
  1273 
       
  1274             tempRefBy.Append( toHdr->Mid( indexLeft,
       
  1275                     indexRight - indexLeft + KSVPSingleBracketLength ) );
       
  1276             }
       
  1277         }
       
  1278     
       
  1279     headers->AppendL( tempRefBy );
       
  1280     CleanupStack::Pop( headers );
       
  1281     
       
  1282     SVPDEBUG1( "CSVPTransferStateContext::SetupHeadersL Out" )
       
  1283     return headers;
       
  1284     }
       
  1285 
       
  1286 // ---------------------------------------------------------------------------
       
  1287 // CSVPTransferStateContext::InitializeStateArrayL
       
  1288 // ---------------------------------------------------------------------------
       
  1289 //
       
  1290 void CSVPTransferStateContext::InitializeStateArrayL()
       
  1291     {
       
  1292     // Create the array of the transfer states.
       
  1293     iStates = new ( ELeave ) RPointerArray<CSVPTransferStateBase>
       
  1294             ( KSVPTransferStateArraySize );
       
  1295     
       
  1296     // Transfer state classes are created here:
       
  1297     // Idle state
       
  1298     CSVPTransferStateBase* state = CSVPTransferIdleState::NewLC();
       
  1299     User::LeaveIfError( iStates->Insert(
       
  1300             state, KSVPTransferIdleStateIndex ) );
       
  1301     CleanupStack::Pop( state );
       
  1302     
       
  1303     // Pending state
       
  1304     state = CSVPTransferPendingState::NewLC();
       
  1305     User::LeaveIfError( iStates->Insert(
       
  1306             state, KSVPTransferPendingStateIndex ) );
       
  1307     CleanupStack::Pop( state );
       
  1308     
       
  1309     // Accepted state
       
  1310     state = CSVPTransferAcceptedState::NewLC();
       
  1311     User::LeaveIfError( iStates->Insert(
       
  1312             state, KSVPTransferAcceptedStateIndex ) );
       
  1313     CleanupStack::Pop( state );
       
  1314     
       
  1315     // Terminating state
       
  1316     state = CSVPTransferTerminatingState::NewLC();
       
  1317     User::LeaveIfError( iStates->Insert(
       
  1318             state, KSVPTransferTerminatingStateIndex ) );
       
  1319     CleanupStack::Pop( state );
       
  1320     
       
  1321     // Terminated state
       
  1322     state = CSVPTransferTerminatedState::NewLC();
       
  1323     User::LeaveIfError( iStates->Insert(
       
  1324             state, KSVPTransferTerminatedStateIndex ) );
       
  1325     CleanupStack::Pop( state );
       
  1326     }
       
  1327 
       
  1328 // -----------------------------------------------------------------------------
       
  1329 // CSVPTransferStateContext::IsStateTransitionAccepted
       
  1330 // -----------------------------------------------------------------------------
       
  1331 //
       
  1332 TBool CSVPTransferStateContext::IsStateTransitionAccepted(
       
  1333         const TSVPTransferStateIndex aNewState )
       
  1334 	{
       
  1335 	TSVPTransferStateIndex current = CurrentState();
       
  1336 	
       
  1337     SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: current  = %d", current )
       
  1338     SVPDEBUG2( "CSVPTransferStateContext::IsStateTransitionAccepted: newstate = %d", aNewState )
       
  1339     
       
  1340     switch( current )
       
  1341         {
       
  1342         case KErrNotFound:
       
  1343             {
       
  1344             // Only idle state can be the first one.
       
  1345             if ( KSVPTransferIdleStateIndex  == aNewState )
       
  1346                 {
       
  1347                 return ETrue;
       
  1348                 }
       
  1349             else
       
  1350                 {
       
  1351                 return EFalse;
       
  1352                 }
       
  1353             }
       
  1354         
       
  1355         case KSVPTransferIdleStateIndex:
       
  1356             {
       
  1357             if ( KSVPTransferPendingStateIndex == aNewState ||
       
  1358                  KSVPTransferTerminatingStateIndex == aNewState )
       
  1359                 {
       
  1360                 return ETrue;
       
  1361                 }
       
  1362             else
       
  1363                 {
       
  1364                 return EFalse;
       
  1365                 }
       
  1366             }
       
  1367         
       
  1368         case KSVPTransferPendingStateIndex:
       
  1369             {
       
  1370             if ( KSVPTransferAcceptedStateIndex == aNewState ||
       
  1371                  KSVPTransferTerminatingStateIndex == aNewState )
       
  1372                 {
       
  1373                 return ETrue;
       
  1374                 }
       
  1375             else
       
  1376                 {
       
  1377                 return EFalse;
       
  1378                 }
       
  1379             }
       
  1380         
       
  1381         case KSVPTransferAcceptedStateIndex:
       
  1382             {
       
  1383             // If in accepted state, new transition is valid (return true).
       
  1384             // No transition actually occurs because
       
  1385             // state "changes" from accepted to accepted.
       
  1386             // This ignores sequent icoming NOTIFY's after REFER has been sent.
       
  1387             if ( KSVPTransferTerminatingStateIndex == aNewState ||
       
  1388                     KSVPTransferAcceptedStateIndex == aNewState)
       
  1389                 {
       
  1390                 return ETrue;
       
  1391                 }
       
  1392             else
       
  1393                 {
       
  1394                 return EFalse;
       
  1395                 }
       
  1396             }
       
  1397         
       
  1398         case KSVPTransferTerminatingStateIndex:
       
  1399             {
       
  1400             // From terminating state, transition to terminated is accepted.
       
  1401             if ( KSVPTransferTerminatingStateIndex == aNewState ||
       
  1402                  KSVPTransferTerminatedStateIndex == aNewState )
       
  1403                 {
       
  1404                 return ETrue;
       
  1405                 }
       
  1406             else
       
  1407                 {
       
  1408                 return EFalse;
       
  1409                 }
       
  1410             }
       
  1411         
       
  1412         case KSVPTransferTerminatedStateIndex:
       
  1413             {
       
  1414             // From terminated state, transition to idle is accepted.
       
  1415             if ( KSVPTransferIdleStateIndex == aNewState )
       
  1416                 {
       
  1417                 return ETrue;
       
  1418                 }
       
  1419             else
       
  1420                 {
       
  1421                 return EFalse;
       
  1422                 }
       
  1423             }
       
  1424         
       
  1425         default:
       
  1426             {
       
  1427             // Should not come here, since all the states are handled
       
  1428             SVPDEBUG1( "CSVPTransferStateContext::IsStateTransitionAccepted - Error" )
       
  1429             return EFalse;
       
  1430             }
       
  1431         // No breaks in switch case due returns.  
       
  1432         }
       
  1433 	}
       
  1434