sipvoipprovider/svptransfer/src/svptransfercontroller.cpp
changeset 0 a4daefaec16c
child 10 ed1e38b404e5
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 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             {
       
   230             if ( iTransferContext->IsAttended() )
       
   231                 {
       
   232                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\
       
   233                     SIP/2.0 200 OK" );
       
   234 
       
   235                 // Attended transfer (F24) 200 OK
       
   236                 if( iCCPTransferObserver )
       
   237                     {
       
   238                     SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
       
   239                     iCCPTransferObserver->TransferEventOccurred( 
       
   240                                 MCCPTransferObserver::ECCPLocalTransfer );  
       
   241                     }
       
   242 
       
   243                 // Set and apply the next state - terminating
       
   244                 iTransferContext->SetCurrentStateL( 
       
   245                                         KSVPTransferTerminatingStateIndex );
       
   246                 iTransferContext->ApplyCurrentStateL();
       
   247 
       
   248                 // Attended transfer is ok, hangup the session
       
   249                 iTransferContext->TransferObserver().TransferNotification(
       
   250                                                       ESVPTransferOKHangUp );
       
   251                 }
       
   252             else
       
   253                 {
       
   254                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended: SIP/2.0 200 OK" );                    
       
   255                 }
       
   256             }
       
   257         else if ( !content->Find( TPtrC8( KSVPNotifyRinging ) ) &&
       
   258                   !iTransferContext->IsAttended())
       
   259             {
       
   260             // Polycom send Ringing instead of Trying in unattended case.
       
   261             SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended and 180 Ringing" );
       
   262 
       
   263             // Check if 202 Accepted already received
       
   264             if ( iAccepted )
       
   265                 { 
       
   266                 // Stop the refer timer
       
   267                 iTransferContext->StopReferTimer( );
       
   268 
       
   269                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: Polycom case" );
       
   270                     
       
   271                 // Unattended transfer: display "transferred" note
       
   272                 if( iCCPTransferObserver )
       
   273                     {
       
   274                     SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
       
   275                     iCCPTransferObserver->TransferEventOccurred( 
       
   276                             MCCPTransferObserver::ECCPLocalTransfer );
       
   277                     }                
       
   278 
       
   279                 // Set and apply the next state - accepted
       
   280                 iTransferContext->SetCurrentStateL( 
       
   281                         KSVPTransferAcceptedStateIndex );
       
   282                 iTransferContext->ApplyCurrentStateL();                
       
   283             
       
   284                 iTransferContext->SetCurrentStateL( 
       
   285                                         KSVPTransferTerminatingStateIndex );
       
   286                 iTransferContext->ApplyCurrentStateL();
       
   287                 // Unattended transfer is ok, hangup the session
       
   288                 iTransferContext->TransferObserver().TransferNotification( 
       
   289                                                       ESVPTransferOKHangUp );
       
   290                 }
       
   291             }
       
   292         else if ( !content->Find( TPtrC8( KSVPNotifyServiceUnavailable ) ) )
       
   293             {
       
   294             // Notify that comes after the accepted refer, if
       
   295             // the (wrong) address of the refer cannot be reached.
       
   296             if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() )
       
   297                 {
       
   298                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503 -> ECCPTransferFailed");
       
   299 
       
   300                 // Set and apply the next state - terminating
       
   301                 iTransferContext->SetCurrentStateL( 
       
   302                                         KSVPTransferTerminatingStateIndex );
       
   303                 iTransferContext->ApplyCurrentStateL();
       
   304 
       
   305                 // Transfer fails, notify client.
       
   306                 iTransferContext->TransferObserver().TransferNotification(
       
   307                                                       ESVPTransferDecline );
       
   308                 }
       
   309             else
       
   310                 {
       
   311                 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503.");
       
   312                 }
       
   313             }
       
   314         else
       
   315             {
       
   316             SVPDEBUG1("CSVPTransferController::NotifyReceivedL:\
       
   317                 Unhandled container content");
       
   318             }
       
   319         
       
   320         // Ownership transferred here   
       
   321         delete content;
       
   322         }
       
   323         
       
   324     SVPDEBUG1("CSVPTransferController::NotifyReceivedL: Out");    
       
   325     }
       
   326     
       
   327     
       
   328 // ---------------------------------------------------------------------------
       
   329 // CSVPTransferController::HandleReferStateChangeL
       
   330 // ---------------------------------------------------------------------------
       
   331 //
       
   332 void CSVPTransferController::HandleReferStateChangeL( CMceRefer& aRefer,
       
   333 				                                TInt aStatusCode )
       
   334     {
       
   335     SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() In");    
       
   336 
       
   337     if ( iTransferContext->MceRefer() == &aRefer )
       
   338         {                          
       
   339         if ( KSVPAcceptedVal == aStatusCode )
       
   340             {
       
   341             // Accepted unattended F6, Attended F16
       
   342             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Accept: %i",
       
   343 			             KSVPAcceptedVal );
       
   344 
       
   345             // Display "transferring" note
       
   346             if( iCCPTransferObserver )
       
   347                 {
       
   348                 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL, send remote transferring" );
       
   349                 iCCPTransferObserver->TransferEventOccurred( 
       
   350                         MCCPTransferObserver::ECCPRemoteTransferring ); 
       
   351                 }
       
   352             // Continue acceptance when also notify F7 / F17 "trying" received
       
   353             iAccepted = ETrue;
       
   354             }
       
   355         else if ( ( KSVPBadRequestVal <= aStatusCode && 
       
   356                     KSVPRequestPendingVal >= aStatusCode ) ||
       
   357                     KSVPDeclineVal == aStatusCode ||
       
   358                     KSVPServerInternalErrorVal == aStatusCode ||
       
   359                     KSVPPreconditionFailureVal == aStatusCode )
       
   360             {
       
   361             // Decline, Request Failure 4xx or Server Failure 5xx
       
   362             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Code: %i", aStatusCode );
       
   363             // Stop the refer timer
       
   364             iTransferContext->StopReferTimer( );
       
   365 
       
   366             // Set and apply the next state - terminating
       
   367             iTransferContext->SetCurrentStateL( 
       
   368                                       KSVPTransferTerminatingStateIndex );
       
   369             iTransferContext->ApplyCurrentStateL();            
       
   370 
       
   371             // Notify the observer about the decline.
       
   372             iTransferContext->TransferObserver().TransferNotification( 
       
   373                                                     ESVPTransferDecline );
       
   374             }
       
   375             
       
   376         else
       
   377             {
       
   378             // Not handled
       
   379             SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: \
       
   380                 Unknown StatusCode: %i", aStatusCode );
       
   381             }
       
   382         }    
       
   383     else
       
   384         {
       
   385         // Unknown refer - not handled
       
   386         SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL: \
       
   387             Unknown refer");
       
   388         }    
       
   389 
       
   390     SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() Out");            
       
   391     }
       
   392         
       
   393             
       
   394 // ---------------------------------------------------------------------------
       
   395 // CSVPTransferController::IncomingReferL
       
   396 // ---------------------------------------------------------------------------
       
   397 //
       
   398 void CSVPTransferController::IncomingReferL( CMceInRefer* aRefer,
       
   399         const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer )
       
   400     {
       
   401     SVPDEBUG1( "CSVPTransferController::IncomingReferL In" )
       
   402     
       
   403     // Is new incoming refer handling possible
       
   404     if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
       
   405         {
       
   406         SVPDEBUG1( "CSVPTransferController::IncomingReferL: allowed" )
       
   407         
       
   408         iTransferContext->SetMceRefer( static_cast<CMceRefer*>( aRefer ) );
       
   409         iTransferContext->SetIncomingReferToL( aReferTo );
       
   410         CDesC8Array* headers = aContainer->GetHeaders();// get headers
       
   411         
       
   412         if ( headers )
       
   413             {
       
   414             TBool found = EFalse;
       
   415             
       
   416             for( TInt i = 0; i < headers->MdcaCount() && !found; i++ )
       
   417                 {
       
   418                 TPtrC8 tmpHeader = headers->MdcaPoint( i );
       
   419                 
       
   420                 if ( KErrNotFound != tmpHeader.FindF( KSVPReferredBy ) )
       
   421                     {
       
   422                     SVPDEBUG1( "KSVPReferredBy found" )
       
   423                     found = ETrue;
       
   424                     iTransferContext->SetIncomingReferredByL( tmpHeader );
       
   425                     }
       
   426                 }
       
   427             }
       
   428         
       
   429         delete headers;
       
   430         headers = NULL;
       
   431         }
       
   432     else
       
   433         {
       
   434         SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed" )
       
   435         User::Leave( KSVPErrTransferStateError );
       
   436         }
       
   437     
       
   438     if ( iTransferContext->IsAttended() )
       
   439         {
       
   440         SVPDEBUG1( "CSVPTransferController::IncomingReferL: Attended case, send accept" )
       
   441         
       
   442         // send trying notification and wait respond for it
       
   443         CMceInEvent* inEvent = NULL;
       
   444         
       
   445         TRAPD( acceptError, inEvent = static_cast<CMceInRefer*>(
       
   446                 iTransferContext->MceRefer() )->AcceptL() );
       
   447         
       
   448         if ( KErrNone == acceptError )
       
   449             {
       
   450             // Apply state, changes to next state (pending)
       
   451             SVPDEBUG1( "CSVPTransferController::IncomingReferL: pending state" )
       
   452             iTransferContext->SetMceEvent( static_cast<CMceEvent*>( inEvent ) );
       
   453             iTransferContext->ApplyCurrentStateL();
       
   454             }
       
   455         else
       
   456             {
       
   457             // Set and apply the next state - terminating
       
   458             SVPDEBUG2("CSVPTransferController::IncomingReferL: acc fails = %d", acceptError )
       
   459             iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   460             iTransferContext->ApplyCurrentStateL();
       
   461             }
       
   462         }
       
   463     else
       
   464         {
       
   465         // Apply state, changes to next state (pending)
       
   466         SVPDEBUG1( "CSVPTransferController::IncomingReferL: UnAttended case pending" )
       
   467         iTransferContext->ApplyCurrentStateL();
       
   468         }
       
   469     
       
   470     SVPDEBUG1( "CSVPTransferController::IncomingReferL Out" )
       
   471     }
       
   472 
       
   473 // ---------------------------------------------------------------------------
       
   474 // CSVPTransferController::IsMceRefer
       
   475 // ---------------------------------------------------------------------------
       
   476 //
       
   477 TBool CSVPTransferController::IsMceRefer( CMceRefer& aRefer )
       
   478     {
       
   479     return ( iTransferContext->MceRefer() == &aRefer );
       
   480     }
       
   481     
       
   482 // ---------------------------------------------------------------------------
       
   483 // CSVPTransferController::IsAttended
       
   484 // ---------------------------------------------------------------------------
       
   485 //
       
   486 TBool CSVPTransferController::IsAttended( )
       
   487     {
       
   488     return ( iTransferContext->IsAttended() );
       
   489     }
       
   490 
       
   491 // ---------------------------------------------------------------------------
       
   492 // CSVPTransferController::SetTransferDataL
       
   493 // ---------------------------------------------------------------------------
       
   494 //
       
   495 void CSVPTransferController::SetTransferDataL( CDesC8Array* aUserAgentHeaders,
       
   496                                                TInt aSecureStatus )
       
   497     {
       
   498     SVPDEBUG1("  CSVPTransferController::SetTransferDataL" );
       
   499     iTransferContext->SetTransferDataL( aUserAgentHeaders, aSecureStatus );
       
   500     }
       
   501 
       
   502 // ---------------------------------------------------------------------------
       
   503 // CSVPTransferController::SetMceSessionObject
       
   504 // ---------------------------------------------------------------------------
       
   505 //
       
   506 void CSVPTransferController::SetMceSessionObject( CMceSession* aSession )
       
   507     {
       
   508     iTransferContext->SetMceSessionObject( aSession );
       
   509     }
       
   510 
       
   511 // ---------------------------------------------------------------------------
       
   512 // CSVPTransferController::SendNotifyL
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 void CSVPTransferController::SendNotifyL( TInt aStatusCode )
       
   516     {
       
   517     SVPDEBUG2("CSVPTransferController::SendNotifyL() code = %d", aStatusCode);
       
   518 
       
   519     CMceInEvent* inEvent = static_cast< CMceInEvent* > (
       
   520                                             iTransferContext->MceEvent());   
       
   521     if (inEvent)
       
   522         {
       
   523         HBufC8* contentType = KSVPMessageSipfrag().AllocLC(); //message/sipfrag
       
   524         HBufC8* content = NULL; 
       
   525     
       
   526         if (KSVPOKVal == aStatusCode )
       
   527             {
       
   528             content = KSVPNotifyOK().AllocLC(); // "SIP/2.0 200 OK"
       
   529             }
       
   530         else if ( KSVPNotFoundVal == aStatusCode ||
       
   531                   KSVPBusyHereVal == aStatusCode ||
       
   532                   KSVPDeclineVal == aStatusCode )
       
   533             {
       
   534             content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
       
   535             }
       
   536         else
       
   537             {
       
   538             SVPDEBUG2("CSVPTransferController::SendNotifyL unknown aStatusCode = %d", aStatusCode);
       
   539             content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
       
   540             }
       
   541 
       
   542         CDesC8Array* headers = NULL;
       
   543         headers = new( ELeave ) CDesC8ArrayFlat( KSVPContactArrayGranularity );
       
   544         CleanupStack::PushL( headers );
       
   545         headers->AppendL( KSVPSubsStateTerminated );
       
   546 
       
   547         // Notify is sent to transferer (unattended  msg F15, attended msg F24)
       
   548         TRAPD( errNotify, inEvent->TerminateL( headers, contentType, content ) );
       
   549 
       
   550         if ( KErrNone == errNotify )
       
   551             {
       
   552             SVPDEBUG1("CSVPTransferController::SendNotifyL, notify sending OK");
       
   553             CleanupStack::Pop( 3, contentType );    // headers, content, contentType
       
   554             }
       
   555         else
       
   556             {
       
   557             // error handling
       
   558             SVPDEBUG2("CSVPTransferController::SendNotifyL: errNotify = %d", errNotify );
       
   559             CleanupStack::PopAndDestroy( 3, contentType );    // headers, content, contentType
       
   560             }
       
   561         }
       
   562         
       
   563     if ( iTransferContext->IsAttended() )
       
   564         {
       
   565         SVPDEBUG1("CSVPTransferController::SendNotifyL() Attended done");
       
   566         }
       
   567     else
       
   568         {
       
   569         SVPDEBUG1("CSVPTransferController::SendNotifyL() UnAttended to terminating state");
       
   570         // Finish unattended incoming transfer sequence
       
   571         // Set and apply the next state - terminating
       
   572         iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   573         iTransferContext->ApplyCurrentStateL();
       
   574         }
       
   575 
       
   576     SVPDEBUG1("CSVPTransferController::SendNotifyL() Out");
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // CSVPTransferController::IsIncomingTransfer
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 TBool CSVPTransferController::IsIncomingTransfer()
       
   584     {
       
   585     SVPDEBUG2("CSVPTransferController::IsIncomingTransfer = %d",
       
   586                 iTransferContext->IsIncoming() );
       
   587     return iTransferContext->IsIncoming();
       
   588     }
       
   589 
       
   590 // ---------------------------------------------------------------------------
       
   591 // CSVPTransferController::TerminateTransfer
       
   592 // ---------------------------------------------------------------------------
       
   593 //
       
   594 void CSVPTransferController::TerminateTransfer()
       
   595     {
       
   596     SVPDEBUG1("CSVPTransferController::TerminateTransfer" )
       
   597     TRAP_IGNORE( TerminateTransferL() );
       
   598     }
       
   599 
       
   600 // ---------------------------------------------------------------------------
       
   601 // CSVPTransferController::TerminateTransferL
       
   602 // ---------------------------------------------------------------------------
       
   603 //
       
   604 void CSVPTransferController::TerminateTransferL()
       
   605     {
       
   606     iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
       
   607     iTransferContext->ApplyCurrentStateL();
       
   608     }
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // CSVPTransferController::AttendedTransfer
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 TInt CSVPTransferController::AttendedTransfer( MCCPCall& aTransferTargetCall )
       
   615     {  
       
   616     SVPDEBUG1( "CSVPTransferController::AttendedTransfer call IN" );
       
   617     TRAPD( transError, TransferL( &aTransferTargetCall, KNullDesC, ETrue ));
       
   618     SVPDEBUG2( "CSVPTransferController::AttendedTransfer A return: %d", transError );
       
   619     return transError;
       
   620     }
       
   621 
       
   622 // ---------------------------------------------------------------------------
       
   623 // CSVPTransferController::AttendedTransfer
       
   624 // ---------------------------------------------------------------------------
       
   625 //
       
   626 TInt CSVPTransferController::AttendedTransfer( const TDesC& aTransferTarget )
       
   627     {  
       
   628     SVPDEBUG1( "CSVPTransferController::AttendedTransfer target IN" );
       
   629     TRAPD( transError, TransferL( NULL, aTransferTarget, ETrue ));
       
   630     SVPDEBUG2( "CSVPTransferController::AttendedTransfer B return: %d", transError );
       
   631     return transError;
       
   632     }
       
   633 
       
   634 // ---------------------------------------------------------------------------
       
   635 // CSVPTransferController::UnattendedTransfer
       
   636 // ---------------------------------------------------------------------------
       
   637 //
       
   638 TInt CSVPTransferController::UnattendedTransfer( const TDesC& aTransferTarget )
       
   639     {  
       
   640     SVPDEBUG1( "CSVPTransferController::UnattendedTransfer IN" );
       
   641     TRAPD( transError, TransferL( NULL, aTransferTarget, EFalse ));
       
   642     SVPDEBUG2( "CSVPTransferController::UnattendedTransfer return: %d", transError );
       
   643     return transError;
       
   644     }
       
   645 
       
   646 // ---------------------------------------------------------------------------
       
   647 // CSVPTransferController::AcceptTransfer
       
   648 // ---------------------------------------------------------------------------
       
   649 //
       
   650 TInt CSVPTransferController::AcceptTransfer( const TBool aAccept )
       
   651     {
       
   652     SVPDEBUG2("CSVPTransferController::AcceptTransfer() IN aAccept = \
       
   653         %d", aAccept);
       
   654     TInt acceptError = KErrNone;
       
   655     TInt stateError = KErrNone;
       
   656     TInt currentState = iTransferContext->CurrentState();
       
   657     CMceInEvent* inEvent(NULL);
       
   658     
       
   659     // Is state "pending"
       
   660     if ( KSVPTransferPendingStateIndex == currentState )
       
   661         {
       
   662         if ( aAccept )
       
   663             {
       
   664             TRAP( acceptError, ( inEvent = static_cast< CMceInRefer* > (iTransferContext->MceRefer())->AcceptL()));
       
   665             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   666                  AcceptL = %d", acceptError);
       
   667             }
       
   668         else
       
   669             {
       
   670             SVPDEBUG1("CSVPTransferController::AcceptTransfer() reject");
       
   671             TRAP( acceptError, ( static_cast< CMceInRefer* > (iTransferContext->MceRefer())->RejectL()) );
       
   672             }
       
   673             
       
   674         if ( KErrNone == acceptError )
       
   675             {
       
   676             if ( aAccept )
       
   677                 {
       
   678                 // Set the received event
       
   679                 iTransferContext->SetMceEvent(static_cast< CMceEvent* >(inEvent));
       
   680                 
       
   681                 // Set and apply the next state - accepted
       
   682                 TRAP( acceptError,
       
   683                     iTransferContext->SetCurrentStateL( 
       
   684                                             KSVPTransferAcceptedStateIndex );
       
   685                     iTransferContext->ApplyCurrentStateL();
       
   686                     );
       
   687                 }
       
   688             else
       
   689                 {
       
   690                 // Set and apply the next state - terminating
       
   691                 TRAP( acceptError,
       
   692                     iTransferContext->SetCurrentStateL( 
       
   693                                             KSVPTransferTerminatingStateIndex );
       
   694                     iTransferContext->ApplyCurrentStateL();        
       
   695                     );
       
   696                 }
       
   697             }
       
   698         else
       
   699             {
       
   700             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   701                  fails = %d", acceptError);
       
   702             // Set and apply the next state - terminating
       
   703             TRAP( stateError,
       
   704                 iTransferContext->SetCurrentStateL( 
       
   705                                         KSVPTransferTerminatingStateIndex );
       
   706                 iTransferContext->ApplyCurrentStateL();
       
   707                 );
       
   708             SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   709                  stateError = %d", stateError);
       
   710             }
       
   711         }
       
   712     else
       
   713         {
       
   714         SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   715              current state is not pending: %d", currentState);       
       
   716         acceptError = KSVPErrTransferStateError;
       
   717         }
       
   718 
       
   719     SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
       
   720          OUT acceptError = %d", acceptError);    
       
   721     return acceptError;
       
   722     }
       
   723 
       
   724 // ---------------------------------------------------------------------------
       
   725 // CSVPTransferController::TransferTarget
       
   726 // ---------------------------------------------------------------------------
       
   727 //
       
   728 const TDesC& CSVPTransferController::TransferTarget() const
       
   729     {   
       
   730     return iTransferContext->IncomingReferTo();
       
   731     }
       
   732 
       
   733 // ---------------------------------------------------------------------------
       
   734 // CSVPTransferController::AddObserverL
       
   735 // ---------------------------------------------------------------------------
       
   736 //    
       
   737 void CSVPTransferController::AddObserverL( 
       
   738                                     const MCCPTransferObserver& aObserver )
       
   739     {
       
   740     SVPDEBUG1("CSVPTransferController::AddObserverL() In");
       
   741     // set transfer observer
       
   742     // only one observer used at a time, replaces current one
       
   743     iCCPTransferObserver = const_cast<MCCPTransferObserver*>(&aObserver);
       
   744 
       
   745     SVPDEBUG1("CSVPTransferController::AddObserverL() Out");
       
   746     }
       
   747 
       
   748 // ---------------------------------------------------------------------------
       
   749 // CSVPTransferController::RemoveObserver
       
   750 // ---------------------------------------------------------------------------
       
   751 //
       
   752 TInt CSVPTransferController::RemoveObserver( 
       
   753                                     const MCCPTransferObserver& aObserver )
       
   754     {
       
   755     SVPDEBUG1("CSVPTransferController::RemoveObserver");
       
   756     TInt err = KErrNone;
       
   757     if ( iCCPTransferObserver == const_cast<MCCPTransferObserver*>
       
   758                 (&aObserver) )
       
   759         {
       
   760         iCCPTransferObserver = NULL;
       
   761         }
       
   762     else
       
   763         {
       
   764         err = KErrNotFound;
       
   765         }
       
   766     return err;
       
   767     }
       
   768 
       
   769 // ---------------------------------------------------------------------------
       
   770 // CSVPTransferController::TransferL
       
   771 // ---------------------------------------------------------------------------
       
   772 //
       
   773 void CSVPTransferController::TransferL( MCCPCall* aCall, 
       
   774                                         const TDesC& aTarget,
       
   775                                         const TBool aAttendedTransfer )
       
   776     {
       
   777     SVPDEBUG1("CSVPTransferController::TransferL() In");
       
   778 
       
   779     // Transfer possible.
       
   780     if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
       
   781         {
       
   782         iAccepted = EFalse;
       
   783         
       
   784         // Set transfer parameters
       
   785         iTransferContext->SetTransferParmsL( 
       
   786                             static_cast< CSVPSessionBase* >(aCall),
       
   787                             aTarget,
       
   788                             aAttendedTransfer );
       
   789 
       
   790         // Apply state, execute the refer and change to next state (pending).
       
   791         iTransferContext->ApplyCurrentStateL();
       
   792         }
       
   793     else
       
   794         {
       
   795         SVPDEBUG1( "CSVPTransferController::TransferL: Error - transfer in progress" );
       
   796         iTransferContext->TransferObserver().TransferFailed( KErrInUse );
       
   797         TerminateTransferL();
       
   798         }
       
   799 
       
   800     SVPDEBUG1("CSVPTransferController::TransferL() OUT");
       
   801     }
       
   802 
       
   803