sipvoipprovider/svptransfer/src/svptransfercontroller.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 controller class, transfer is controlled through 
       
    15 *                this class
       
    16 *
       
    17 */
       
    18 
       
    19 #include <mceinrefer.h>                     // CMceInRefer
       
    20 #include <mceinevent.h>                     // CMceEvent, CMceInEvent
       
    21 #include <mcetransactiondatacontainer.h>    // TMceTransactionDataContainer
       
    22 
       
    23 #include "svptransfercontroller.h"
       
    24 #include "svptransferstatecontext.h"
       
    25 #include "svplogger.h"
       
    26 #include "svpsessionbase.h"             // CSVPSessionBase
       
    27 #include "svpsipconsts.h"
       
    28 #include "svpconsts.h"
       
    29 
       
    30 // ---------------------------------------------------------------------------
       
    31 // CSVPTransferController::CSVPTransferController
       
    32 // ---------------------------------------------------------------------------
       
    33 //
       
    34 CSVPTransferController::CSVPTransferController() :
       
    35     iTransferContext (NULL),
       
    36     iCCPTransferObserver (NULL),
       
    37     iAccepted( EFalse )
       
    38     {
       
    39     }
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // CSVPTransferController::ConstructL
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 void CSVPTransferController::ConstructL( 
       
    46                                 CMceSession* aMceSession,
       
    47                                 CSVPSessionBase* aSVPSession,
       
    48                                 TMceTransactionDataContainer& aContainer, 
       
    49                                 MSVPTransferObserver& aObserver )
       
    50     {
       
    51     // Transfer state context
       
    52     iTransferContext = CSVPTransferStateContext::NewL( 
       
    53                                 aMceSession, aSVPSession, 
       
    54                                 aContainer, aObserver );
       
    55     }
       
    56     
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // CSVPTransferController::NewL
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CSVPTransferController* CSVPTransferController::NewL( 
       
    63                             CMceSession* aMceSession,
       
    64                             CSVPSessionBase* aSVPSession,
       
    65                             TMceTransactionDataContainer& aContainer, 
       
    66                             MSVPTransferObserver& aObserver )
       
    67     {
       
    68     CSVPTransferController* self = CSVPTransferController::NewLC( 
       
    69                                         aMceSession, 
       
    70                                         aSVPSession,
       
    71                                         aContainer,
       
    72                                         aObserver );
       
    73     CleanupStack::Pop( self );
       
    74     return self;
       
    75     }
       
    76 
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // CSVPTransferController::NewLC
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 CSVPTransferController* CSVPTransferController::NewLC( 
       
    83                             CMceSession* aMceSession,
       
    84                             CSVPSessionBase* aSVPSession,
       
    85                             TMceTransactionDataContainer& aContainer, 
       
    86                             MSVPTransferObserver& aObserver )
       
    87     {
       
    88     CSVPTransferController* self = new( ELeave ) CSVPTransferController;
       
    89     CleanupStack::PushL( self );
       
    90     self->ConstructL( aMceSession, aSVPSession, aContainer, aObserver );
       
    91     return self;
       
    92     }
       
    93     
       
    94 
       
    95 // ---------------------------------------------------------------------------
       
    96 // CSVPTransferController::~CSVPTransferController
       
    97 // ---------------------------------------------------------------------------
       
    98 //
       
    99 CSVPTransferController::~CSVPTransferController()
       
   100     {
       
   101     delete iTransferContext;
       
   102     }
       
   103     
       
   104 
       
   105 // ---------------------------------------------------------------------------
       
   106 // Handle mce event observer notify events. 
       
   107 // The state of the event has changed.
       
   108 // ---------------------------------------------------------------------------
       
   109 //
       
   110 void CSVPTransferController::HandleEventStateChangedL( 
       
   111                             CMceEvent& /* aEvent */,
       
   112                             TInt aStatusCode )
       
   113     {
       
   114     if ( KSVPOKVal == aStatusCode )
       
   115         {
       
   116         if ( iTransferContext->IsAttended() )
       
   117             {
       
   118             SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal & attended" );
       
   119             if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState())
       
   120                 {
       
   121                 // F25 OK received - already acccepted 
       
   122                 // leave for not to create new session later
       
   123                 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: transfer in progress");
       
   124                 User::Leave( KSVPErrTransferInProgress );
       
   125                 }
       
   126 
       
   127             // F18 OK received as response for "trying"
       
   128             // Set and apply the next state - accepted
       
   129             iTransferContext->SetCurrentStateL( KSVPTransferAcceptedStateIndex );
       
   130             iTransferContext->ApplyCurrentStateL();
       
   131             SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL:ApplyCurrentStateL done" );
       
   132             }
       
   133         else    // unattended transfer
       
   134             {
       
   135             SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal unattended" );
       
   136             if ( iTransferContext->CheckIsSessionRemoteHold() &&
       
   137                  KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() )
       
   138                 {
       
   139                 // Transferer has put transferee on hold before sending refer
       
   140                 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: Snom or similar as transferer" );
       
   141                 SendNotifyL( aStatusCode ); // 200 OK
       
   142                 }
       
   143             }
       
   144         }
       
   145     else
       
   146         {
       
   147         SVPDEBUG2("CSVPTransferController::HandleEventStateChangedL: aStatusCode = %d",
       
   148               aStatusCode);
       
   149         }
       
   150     SVPDEBUG1("CSVPTransferController::HandleEventStateChangedL: Out");    
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // CSVPTransferController::NotifyReceivedL
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 void CSVPTransferController::NotifyReceivedL( 
       
   158                             CMceEvent& aEvent,
       
   159                             TMceTransactionDataContainer* aContainer )
       
   160     {
       
   161     SVPDEBUG1("CSVPTransferController::NotifyReceivedL: In");    
       
   162     
       
   163     // check data container and match the event to the active refer event
       
   164     if ( aContainer && iTransferContext->MceEvent() == &aEvent )
       
   165         {                  
       
   166         TInt statusCode = aContainer->GetStatusCode();        
       
   167         HBufC8* content = aContainer->GetContent();
       
   168         
       
   169         SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\
       
   170             statusCode: %d", statusCode );
       
   171         SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\
       
   172             aContainer->GetContent()->Length(): %d", content->Length() );
       
   173 
       
   174         if ( !content->Find( TPtrC8( KSVPNotifyTrying ) ) )
       
   175             {
       
   176             if ( iTransferContext->IsAttended() )
       
   177                 {                
       
   178                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\
       
   179                     SIP/2.0 100 Trying" );
       
   180 
       
   181                 // Attended transfer (F17) NOTIFY , transferee is trying establish new session.
       
   182                 // Check if 202 Accepted already received
       
   183                 if ( iAccepted )
       
   184                     {
       
   185                     // Stop the refer timer
       
   186                     iTransferContext->StopReferTimer( );
       
   187                     // Set and apply the next state - accepted
       
   188                     iTransferContext->SetCurrentStateL( 
       
   189                                     KSVPTransferAcceptedStateIndex );
       
   190                     iTransferContext->ApplyCurrentStateL();
       
   191                     }
       
   192                 }
       
   193             else
       
   194                 {
       
   195                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended case:\
       
   196                     SIP/2.0 100 Trying" );
       
   197 
       
   198                 // Check if 202 Accepted already received
       
   199                 if ( iAccepted )
       
   200                     { 
       
   201                     // Stop the refer timer
       
   202                     iTransferContext->StopReferTimer( );
       
   203 
       
   204                     SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: is accepted" );
       
   205                         
       
   206                     // Unattended transfer: F7 NOTIFY, display "transferred" note
       
   207                     if( iCCPTransferObserver )
       
   208                         {
       
   209                         SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
       
   210                         iCCPTransferObserver->TransferEventOccurred( 
       
   211                                 MCCPTransferObserver::ECCPLocalTransfer );
       
   212                         }                
       
   213 
       
   214                     // Set and apply the next state - accepted
       
   215                     iTransferContext->SetCurrentStateL( 
       
   216                             KSVPTransferAcceptedStateIndex );
       
   217                     iTransferContext->ApplyCurrentStateL();                
       
   218                 
       
   219                     iTransferContext->SetCurrentStateL( 
       
   220                                             KSVPTransferTerminatingStateIndex );
       
   221                     iTransferContext->ApplyCurrentStateL();
       
   222                     // Unattended transfer is ok, hangup the session
       
   223                     iTransferContext->TransferObserver().TransferNotification( 
       
   224                                                           ESVPTransferOKHangUp );
       
   225                     }
       
   226                 }
       
   227             }
       
   228         else if ( !content->Find( TPtrC8( KSVPNotifyOK ) ) || 
       
   229                   !content->Find( TPtrC8( KSVPNotifyOk2 ) ) )
       
   230             {
       
   231             if ( iTransferContext->IsAttended() )
       
   232                 {
       
   233                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\
       
   234                     SIP/2.0 200 OK" );
       
   235 
       
   236                 // Attended transfer (F24) 200 OK
       
   237                 if( iCCPTransferObserver )
       
   238                     {
       
   239                     SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
       
   240                     iCCPTransferObserver->TransferEventOccurred( 
       
   241                                 MCCPTransferObserver::ECCPLocalTransfer );  
       
   242                     }
       
   243 
       
   244                 // Set and apply the next state - terminating
       
   245                 iTransferContext->SetCurrentStateL( 
       
   246                                         KSVPTransferTerminatingStateIndex );
       
   247                 iTransferContext->ApplyCurrentStateL();
       
   248 
       
   249                 // Attended transfer is ok, hangup the session
       
   250                 iTransferContext->TransferObserver().TransferNotification(
       
   251                                                       ESVPTransferOKHangUp );
       
   252                 }
       
   253             else
       
   254                 {
       
   255                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended: SIP/2.0 200 OK" );                    
       
   256                 }
       
   257             }
       
   258         else if ( ( !content->Find( TPtrC8( KSVPNotifyRinging ) ) || 
       
   259                     !content->Find( TPtrC8( KSVPNotifyRinging183 ) ) ) &&
       
   260                     !iTransferContext->IsAttended())
       
   261             {
       
   262             // Polycom send Ringing instead of Trying in unattended case.
       
   263             SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended and Ringing" );
       
   264 
       
   265             // Check if 202 Accepted already received
       
   266             if ( iAccepted )
       
   267                 { 
       
   268                 // Stop the refer timer
       
   269                 iTransferContext->StopReferTimer( );
       
   270 
       
   271                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: Polycom case" );
       
   272                     
       
   273                 // Unattended transfer: display "transferred" note
       
   274                 if( iCCPTransferObserver )
       
   275                     {
       
   276                     SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
       
   277                     iCCPTransferObserver->TransferEventOccurred( 
       
   278                             MCCPTransferObserver::ECCPLocalTransfer );
       
   279                     }                
       
   280 
       
   281                 // Set and apply the next state - accepted
       
   282                 iTransferContext->SetCurrentStateL( 
       
   283                         KSVPTransferAcceptedStateIndex );
       
   284                 iTransferContext->ApplyCurrentStateL();                
       
   285             
       
   286                 iTransferContext->SetCurrentStateL( 
       
   287                                         KSVPTransferTerminatingStateIndex );
       
   288                 iTransferContext->ApplyCurrentStateL();
       
   289                 // Unattended transfer is ok, hangup the session
       
   290                 iTransferContext->TransferObserver().TransferNotification( 
       
   291                                                       ESVPTransferOKHangUp );
       
   292                 }
       
   293             }
       
   294         else if ( !content->Find( TPtrC8( KSVPNotifyServiceUnavailable ) ) )
       
   295             {
       
   296             // Notify that comes after the accepted refer, if
       
   297             // the (wrong) address of the refer cannot be reached.
       
   298             if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() )
       
   299                 {
       
   300                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503 -> ECCPTransferFailed");
       
   301 
       
   302                 // Set and apply the next state - terminating
       
   303                 iTransferContext->SetCurrentStateL( 
       
   304                                         KSVPTransferTerminatingStateIndex );
       
   305                 iTransferContext->ApplyCurrentStateL();
       
   306 
       
   307                 // Transfer fails, notify client.
       
   308                 iTransferContext->TransferObserver().TransferNotification(
       
   309                                                       ESVPTransferDecline );
       
   310                 }
       
   311             else
       
   312                 {
       
   313                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503.");
       
   314                 }
       
   315             }
       
   316         else
       
   317             {
       
   318             SVPDEBUG1("CSVPTransferController::NotifyReceivedL:\
       
   319                 Unhandled container content");
       
   320             }
       
   321         
       
   322         // Ownership transferred here   
       
   323         delete content;
       
   324         }
       
   325         
       
   326     SVPDEBUG1("CSVPTransferController::NotifyReceivedL: Out");    
       
   327     }
       
   328     
       
   329     
       
   330 // ---------------------------------------------------------------------------
       
   331 // CSVPTransferController::HandleReferStateChangeL
       
   332 // ---------------------------------------------------------------------------
       
   333 //
       
   334 void CSVPTransferController::HandleReferStateChangeL( CMceRefer& aRefer,
       
   335 				                                TInt aStatusCode )
       
   336     {
       
   337     SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() In");    
       
   338 
       
   339     if ( iTransferContext->MceRefer() == &aRefer )
       
   340         {                          
       
   341         if ( KSVPAcceptedVal == aStatusCode )
       
   342             {
       
   343             // Accepted unattended F6, Attended F16
       
   344             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Accept: %i",
       
   345 			             KSVPAcceptedVal );
       
   346 
       
   347             // Display "transferring" note
       
   348             if( iCCPTransferObserver )
       
   349                 {
       
   350                 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL, send remote transferring" );
       
   351                 iCCPTransferObserver->TransferEventOccurred( 
       
   352                         MCCPTransferObserver::ECCPRemoteTransferring ); 
       
   353                 }
       
   354             // Continue acceptance when also notify F7 / F17 "trying" received
       
   355             iAccepted = ETrue;
       
   356             }
       
   357         else if ( ( KSVPBadRequestVal <= aStatusCode && 
       
   358                     KSVPRequestPendingVal >= aStatusCode ) ||
       
   359                     KSVPDeclineVal == aStatusCode ||
       
   360                     KSVPServerInternalErrorVal == aStatusCode ||
       
   361                     KSVPPreconditionFailureVal == aStatusCode )
       
   362             {
       
   363             // Decline, Request Failure 4xx or Server Failure 5xx
       
   364             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Code: %i", aStatusCode );
       
   365             // Stop the refer timer
       
   366             iTransferContext->StopReferTimer( );
       
   367 
       
   368             // Set and apply the next state - terminating
       
   369             iTransferContext->SetCurrentStateL( 
       
   370                                       KSVPTransferTerminatingStateIndex );
       
   371             iTransferContext->ApplyCurrentStateL();            
       
   372 
       
   373             // Notify the observer about the decline.
       
   374             iTransferContext->TransferObserver().TransferNotification( 
       
   375                                                     ESVPTransferDecline );
       
   376             }
       
   377             
       
   378         else
       
   379             {
       
   380             // Not handled
       
   381             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: \
       
   382                 Unknown StatusCode: %i", aStatusCode );
       
   383             }
       
   384         }    
       
   385     else
       
   386         {
       
   387         // Unknown refer - not handled
       
   388         SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL: \
       
   389             Unknown refer");
       
   390         }    
       
   391 
       
   392     SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() Out");            
       
   393     }
       
   394         
       
   395             
       
   396 // ---------------------------------------------------------------------------
       
   397 // CSVPTransferController::IncomingReferL
       
   398 // ---------------------------------------------------------------------------
       
   399 //
       
   400 void CSVPTransferController::IncomingReferL( CMceInRefer* aRefer,
       
   401         const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer )
       
   402     {
       
   403     SVPDEBUG1( "CSVPTransferController::IncomingReferL In" )
       
   404     
       
   405     // Is new incoming refer handling possible
       
   406     if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
       
   407         {
       
   408         SVPDEBUG1( "CSVPTransferController::IncomingReferL: allowed" )
       
   409         
       
   410         iTransferContext->SetMceRefer( static_cast<CMceRefer*>( aRefer ) );
       
   411         iTransferContext->SetIncomingReferToL( aReferTo );
       
   412         CDesC8Array* headers = aContainer->GetHeaders();// get headers
       
   413         
       
   414         if ( headers )
       
   415             {
       
   416             TBool found = EFalse;
       
   417             
       
   418             for( TInt i = 0; i < headers->MdcaCount() && !found; i++ )
       
   419                 {
       
   420                 TPtrC8 tmpHeader = headers->MdcaPoint( i );
       
   421                 
       
   422                 if ( KErrNotFound != tmpHeader.FindF( KSVPReferredBy ) )
       
   423                     {
       
   424                     SVPDEBUG1( "KSVPReferredBy found" )
       
   425                     found = ETrue;
       
   426                     iTransferContext->SetIncomingReferredByL( tmpHeader );
       
   427                     }
       
   428                 }
       
   429             }
       
   430         
       
   431         delete headers;
       
   432         headers = NULL;
       
   433         }
       
   434     
       
   435     else if ( KSVPTransferPendingStateIndex == iTransferContext->CurrentState() )
       
   436         {
       
   437         SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed \
       
   438             -> ignore" )
       
   439         User::Leave( KSVPErrTransferInProgress );
       
   440         }
       
   441     
       
   442     else
       
   443         {
       
   444         SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed" )
       
   445         User::Leave( KSVPErrTransferStateError );
       
   446         }
       
   447     
       
   448     if ( iTransferContext->IsAttended() )
       
   449         {
       
   450         SVPDEBUG1( "CSVPTransferController::IncomingReferL: Attended case, send accept" )
       
   451         
       
   452         // send trying notification and wait respond for it
       
   453         CMceInEvent* inEvent = NULL;
       
   454         
       
   455         TRAPD( acceptError, inEvent = static_cast<CMceInRefer*>(
       
   456                 iTransferContext->MceRefer() )->AcceptL() );
       
   457         
       
   458         if ( KErrNone == acceptError )
       
   459             {
       
   460             // Apply state, changes to next state (pending)
       
   461             SVPDEBUG1( "CSVPTransferController::IncomingReferL: pending state" )
       
   462             iTransferContext->SetMceEvent( static_cast<CMceEvent*>( inEvent ) );
       
   463             iTransferContext->ApplyCurrentStateL();
       
   464             }
       
   465         else
       
   466             {
       
   467             // Set and apply the next state - terminating
       
   468             SVPDEBUG2("CSVPTransferController::IncomingReferL: acc fails = %d", acceptError )
       
   469             iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   470             iTransferContext->ApplyCurrentStateL();
       
   471             }
       
   472         }
       
   473     else
       
   474         {
       
   475         // Apply state, changes to next state (pending)
       
   476         SVPDEBUG1( "CSVPTransferController::IncomingReferL: UnAttended case pending" )
       
   477         iTransferContext->ApplyCurrentStateL();
       
   478         }
       
   479     
       
   480     SVPDEBUG1( "CSVPTransferController::IncomingReferL Out" )
       
   481     }
       
   482 
       
   483 // ---------------------------------------------------------------------------
       
   484 // CSVPTransferController::IsMceRefer
       
   485 // ---------------------------------------------------------------------------
       
   486 //
       
   487 TBool CSVPTransferController::IsMceRefer( CMceRefer& aRefer )
       
   488     {
       
   489     return ( iTransferContext->MceRefer() == &aRefer );
       
   490     }
       
   491     
       
   492 // ---------------------------------------------------------------------------
       
   493 // CSVPTransferController::IsAttended
       
   494 // ---------------------------------------------------------------------------
       
   495 //
       
   496 TBool CSVPTransferController::IsAttended( )
       
   497     {
       
   498     return ( iTransferContext->IsAttended() );
       
   499     }
       
   500 
       
   501 // ---------------------------------------------------------------------------
       
   502 // CSVPTransferController::SetTransferDataL
       
   503 // ---------------------------------------------------------------------------
       
   504 //
       
   505 void CSVPTransferController::SetTransferDataL( CDesC8Array* aUserAgentHeaders,
       
   506                                                TInt aSecureStatus )
       
   507     {
       
   508     SVPDEBUG1("  CSVPTransferController::SetTransferDataL" );
       
   509     iTransferContext->SetTransferDataL( aUserAgentHeaders, aSecureStatus );
       
   510     }
       
   511 
       
   512 // ---------------------------------------------------------------------------
       
   513 // CSVPTransferController::SetMceSessionObject
       
   514 // ---------------------------------------------------------------------------
       
   515 //
       
   516 void CSVPTransferController::SetMceSessionObject( CMceSession* aSession )
       
   517     {
       
   518     iTransferContext->SetMceSessionObject( aSession );
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------------------------
       
   522 // CSVPTransferController::SendNotifyL
       
   523 // ---------------------------------------------------------------------------
       
   524 //
       
   525 void CSVPTransferController::SendNotifyL( TInt aStatusCode )
       
   526     {
       
   527     SVPDEBUG2("CSVPTransferController::SendNotifyL() code = %d", aStatusCode);
       
   528 
       
   529     CMceInEvent* inEvent = static_cast< CMceInEvent* > (
       
   530                                             iTransferContext->MceEvent());   
       
   531     if (inEvent)
       
   532         {
       
   533         HBufC8* contentType = KSVPMessageSipfrag().AllocLC(); //message/sipfrag
       
   534         HBufC8* content = NULL; 
       
   535     
       
   536         if (KSVPOKVal == aStatusCode )
       
   537             {
       
   538             content = KSVPNotifyOK().AllocLC(); // "SIP/2.0 200 OK"
       
   539             }
       
   540         else if ( KSVPNotFoundVal == aStatusCode ||
       
   541                   KSVPBusyHereVal == aStatusCode ||
       
   542                   KSVPDeclineVal == aStatusCode )
       
   543             {
       
   544             content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
       
   545             }
       
   546         else
       
   547             {
       
   548             SVPDEBUG2("CSVPTransferController::SendNotifyL unknown aStatusCode = %d", aStatusCode);
       
   549             content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
       
   550             }
       
   551 
       
   552         CDesC8Array* headers = NULL;
       
   553         headers = new( ELeave ) CDesC8ArrayFlat( KSVPContactArrayGranularity );
       
   554         CleanupStack::PushL( headers );
       
   555         headers->AppendL( KSVPSubsStateTerminated );
       
   556 
       
   557         // Notify is sent to transferer (unattended  msg F15, attended msg F24)
       
   558         TRAPD( errNotify, inEvent->TerminateL( headers, contentType, content ) );
       
   559 
       
   560         if ( KErrNone == errNotify )
       
   561             {
       
   562             SVPDEBUG1("CSVPTransferController::SendNotifyL, notify sending OK");
       
   563             CleanupStack::Pop( 3, contentType );    // headers, content, contentType
       
   564             }
       
   565         else
       
   566             {
       
   567             // error handling
       
   568             SVPDEBUG2("CSVPTransferController::SendNotifyL: errNotify = %d", errNotify );
       
   569             CleanupStack::PopAndDestroy( 3, contentType );    // headers, content, contentType
       
   570             }
       
   571         }
       
   572         
       
   573     if ( iTransferContext->IsAttended() )
       
   574         {
       
   575         SVPDEBUG1("CSVPTransferController::SendNotifyL() Attended done");
       
   576         }
       
   577     else
       
   578         {
       
   579         SVPDEBUG1("CSVPTransferController::SendNotifyL() UnAttended to terminating state");
       
   580         // Finish unattended incoming transfer sequence
       
   581         // Set and apply the next state - terminating
       
   582         iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   583         iTransferContext->ApplyCurrentStateL();
       
   584         }
       
   585 
       
   586     SVPDEBUG1("CSVPTransferController::SendNotifyL() Out");
       
   587     }
       
   588 
       
   589 // ---------------------------------------------------------------------------
       
   590 // CSVPTransferController::IsIncomingTransfer
       
   591 // ---------------------------------------------------------------------------
       
   592 //
       
   593 TBool CSVPTransferController::IsIncomingTransfer()
       
   594     {
       
   595     SVPDEBUG2("CSVPTransferController::IsIncomingTransfer = %d",
       
   596                 iTransferContext->IsIncoming() );
       
   597     return iTransferContext->IsIncoming();
       
   598     }
       
   599 
       
   600 // ---------------------------------------------------------------------------
       
   601 // CSVPTransferController::TerminateTransfer
       
   602 // ---------------------------------------------------------------------------
       
   603 //
       
   604 void CSVPTransferController::TerminateTransfer()
       
   605     {
       
   606     SVPDEBUG1("CSVPTransferController::TerminateTransfer" )
       
   607     TRAP_IGNORE( TerminateTransferL() );
       
   608     }
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // CSVPTransferController::TerminateTransferL
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 void CSVPTransferController::TerminateTransferL()
       
   615     {
       
   616     iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   617     iTransferContext->ApplyCurrentStateL();
       
   618     }
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // CSVPTransferController::AttendedTransfer
       
   622 // ---------------------------------------------------------------------------
       
   623 //
       
   624 TInt CSVPTransferController::AttendedTransfer( MCCPCall& aTransferTargetCall )
       
   625     {  
       
   626     SVPDEBUG1( "CSVPTransferController::AttendedTransfer call IN" );
       
   627     TRAPD( transError, TransferL( &aTransferTargetCall, KNullDesC, ETrue ));
       
   628     SVPDEBUG2( "CSVPTransferController::AttendedTransfer A return: %d", transError );
       
   629     return transError;
       
   630     }
       
   631 
       
   632 // ---------------------------------------------------------------------------
       
   633 // CSVPTransferController::AttendedTransfer
       
   634 // ---------------------------------------------------------------------------
       
   635 //
       
   636 TInt CSVPTransferController::AttendedTransfer( const TDesC& aTransferTarget )
       
   637     {  
       
   638     SVPDEBUG1( "CSVPTransferController::AttendedTransfer target IN" );
       
   639     TRAPD( transError, TransferL( NULL, aTransferTarget, ETrue ));
       
   640     SVPDEBUG2( "CSVPTransferController::AttendedTransfer B return: %d", transError );
       
   641     return transError;
       
   642     }
       
   643 
       
   644 // ---------------------------------------------------------------------------
       
   645 // CSVPTransferController::UnattendedTransfer
       
   646 // ---------------------------------------------------------------------------
       
   647 //
       
   648 TInt CSVPTransferController::UnattendedTransfer( const TDesC& aTransferTarget )
       
   649     {  
       
   650     SVPDEBUG1( "CSVPTransferController::UnattendedTransfer IN" );
       
   651     TRAPD( transError, TransferL( NULL, aTransferTarget, EFalse ));
       
   652     SVPDEBUG2( "CSVPTransferController::UnattendedTransfer return: %d", transError );
       
   653     return transError;
       
   654     }
       
   655 
       
   656 // ---------------------------------------------------------------------------
       
   657 // CSVPTransferController::AcceptTransfer
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 TInt CSVPTransferController::AcceptTransfer( const TBool aAccept )
       
   661     {
       
   662     SVPDEBUG2("CSVPTransferController::AcceptTransfer() IN aAccept = \
       
   663         %d", aAccept);
       
   664     TInt acceptError = KErrNone;
       
   665     TInt stateError = KErrNone;
       
   666     TInt currentState = iTransferContext->CurrentState();
       
   667     CMceInEvent* inEvent(NULL);
       
   668     
       
   669     // Is state "pending"
       
   670     if ( KSVPTransferPendingStateIndex == currentState )
       
   671         {
       
   672         if ( aAccept )
       
   673             {
       
   674             TRAP( acceptError, ( inEvent = static_cast< CMceInRefer* > (iTransferContext->MceRefer())->AcceptL()));
       
   675             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   676                  AcceptL = %d", acceptError);
       
   677             }
       
   678         else
       
   679             {
       
   680             SVPDEBUG1("CSVPTransferController::AcceptTransfer() reject");
       
   681             TRAP( acceptError, ( static_cast< CMceInRefer* > (iTransferContext->MceRefer())->RejectL()) );
       
   682             }
       
   683             
       
   684         if ( KErrNone == acceptError )
       
   685             {
       
   686             if ( aAccept )
       
   687                 {
       
   688                 // Set the received event
       
   689                 iTransferContext->SetMceEvent(static_cast< CMceEvent* >(inEvent));
       
   690                 
       
   691                 // Set and apply the next state - accepted
       
   692                 TRAP( acceptError,
       
   693                     iTransferContext->SetCurrentStateL( 
       
   694                                             KSVPTransferAcceptedStateIndex );
       
   695                     iTransferContext->ApplyCurrentStateL();
       
   696                     );
       
   697                 }
       
   698             else
       
   699                 {
       
   700                 // Set and apply the next state - terminating
       
   701                 TRAP( acceptError,
       
   702                     iTransferContext->SetCurrentStateL( 
       
   703                                             KSVPTransferTerminatingStateIndex );
       
   704                     iTransferContext->ApplyCurrentStateL();        
       
   705                     );
       
   706                 }
       
   707             }
       
   708         else
       
   709             {
       
   710             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   711                  fails = %d", acceptError);
       
   712             // Set and apply the next state - terminating
       
   713             TRAP( stateError,
       
   714                 iTransferContext->SetCurrentStateL( 
       
   715                                         KSVPTransferTerminatingStateIndex );
       
   716                 iTransferContext->ApplyCurrentStateL();
       
   717                 );
       
   718             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   719                  stateError = %d", stateError);
       
   720             }
       
   721         }
       
   722     else
       
   723         {
       
   724         SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   725              current state is not pending: %d", currentState);       
       
   726         acceptError = KSVPErrTransferStateError;
       
   727         }
       
   728 
       
   729     SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   730          OUT acceptError = %d", acceptError);    
       
   731     return acceptError;
       
   732     }
       
   733 
       
   734 // ---------------------------------------------------------------------------
       
   735 // CSVPTransferController::TransferTarget
       
   736 // ---------------------------------------------------------------------------
       
   737 //
       
   738 const TDesC& CSVPTransferController::TransferTarget() const
       
   739     {   
       
   740     return iTransferContext->IncomingReferTo();
       
   741     }
       
   742 
       
   743 // ---------------------------------------------------------------------------
       
   744 // CSVPTransferController::AddObserverL
       
   745 // ---------------------------------------------------------------------------
       
   746 //    
       
   747 void CSVPTransferController::AddObserverL( 
       
   748                                     const MCCPTransferObserver& aObserver )
       
   749     {
       
   750     SVPDEBUG1("CSVPTransferController::AddObserverL() In");
       
   751     // set transfer observer
       
   752     // only one observer used at a time, replaces current one
       
   753     iCCPTransferObserver = const_cast<MCCPTransferObserver*>(&aObserver);
       
   754 
       
   755     SVPDEBUG1("CSVPTransferController::AddObserverL() Out");
       
   756     }
       
   757 
       
   758 // ---------------------------------------------------------------------------
       
   759 // CSVPTransferController::RemoveObserver
       
   760 // ---------------------------------------------------------------------------
       
   761 //
       
   762 TInt CSVPTransferController::RemoveObserver( 
       
   763                                     const MCCPTransferObserver& aObserver )
       
   764     {
       
   765     SVPDEBUG1("CSVPTransferController::RemoveObserver");
       
   766     TInt err = KErrNone;
       
   767     if ( iCCPTransferObserver == const_cast<MCCPTransferObserver*>
       
   768                 (&aObserver) )
       
   769         {
       
   770         iCCPTransferObserver = NULL;
       
   771         }
       
   772     else
       
   773         {
       
   774         err = KErrNotFound;
       
   775         }
       
   776     return err;
       
   777     }
       
   778 
       
   779 // ---------------------------------------------------------------------------
       
   780 // CSVPTransferController::TransferL
       
   781 // ---------------------------------------------------------------------------
       
   782 //
       
   783 void CSVPTransferController::TransferL( MCCPCall* aCall, 
       
   784                                         const TDesC& aTarget,
       
   785                                         const TBool aAttendedTransfer )
       
   786     {
       
   787     SVPDEBUG1("CSVPTransferController::TransferL() In");
       
   788 
       
   789     // Transfer possible.
       
   790     if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
       
   791         {
       
   792         iAccepted = EFalse;
       
   793         
       
   794         // Set transfer parameters
       
   795         iTransferContext->SetTransferParmsL( 
       
   796                             static_cast< CSVPSessionBase* >(aCall),
       
   797                             aTarget,
       
   798                             aAttendedTransfer );
       
   799 
       
   800         // Apply state, execute the refer and change to next state (pending).
       
   801         iTransferContext->ApplyCurrentStateL();
       
   802         }
       
   803     else
       
   804         {
       
   805         SVPDEBUG1( "CSVPTransferController::TransferL: Error - transfer in progress" );
       
   806         iTransferContext->TransferObserver().TransferFailed( KErrInUse );
       
   807         TerminateTransferL();
       
   808         }
       
   809 
       
   810     SVPDEBUG1("CSVPTransferController::TransferL() OUT");
       
   811     }
       
   812 
       
   813