--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sipvoipprovider/svptransfer/src/svptransfercontroller.cpp Wed Sep 01 12:29:57 2010 +0100
@@ -0,0 +1,813 @@
+/*
+* Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Transfer controller class, transfer is controlled through
+* this class
+*
+*/
+
+#include <mceinrefer.h> // CMceInRefer
+#include <mceinevent.h> // CMceEvent, CMceInEvent
+#include <mcetransactiondatacontainer.h> // TMceTransactionDataContainer
+
+#include "svptransfercontroller.h"
+#include "svptransferstatecontext.h"
+#include "svplogger.h"
+#include "svpsessionbase.h" // CSVPSessionBase
+#include "svpsipconsts.h"
+#include "svpconsts.h"
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::CSVPTransferController
+// ---------------------------------------------------------------------------
+//
+CSVPTransferController::CSVPTransferController() :
+ iTransferContext (NULL),
+ iCCPTransferObserver (NULL),
+ iAccepted( EFalse )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::ConstructL(
+ CMceSession* aMceSession,
+ CSVPSessionBase* aSVPSession,
+ TMceTransactionDataContainer& aContainer,
+ MSVPTransferObserver& aObserver )
+ {
+ // Transfer state context
+ iTransferContext = CSVPTransferStateContext::NewL(
+ aMceSession, aSVPSession,
+ aContainer, aObserver );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::NewL
+// ---------------------------------------------------------------------------
+//
+CSVPTransferController* CSVPTransferController::NewL(
+ CMceSession* aMceSession,
+ CSVPSessionBase* aSVPSession,
+ TMceTransactionDataContainer& aContainer,
+ MSVPTransferObserver& aObserver )
+ {
+ CSVPTransferController* self = CSVPTransferController::NewLC(
+ aMceSession,
+ aSVPSession,
+ aContainer,
+ aObserver );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::NewLC
+// ---------------------------------------------------------------------------
+//
+CSVPTransferController* CSVPTransferController::NewLC(
+ CMceSession* aMceSession,
+ CSVPSessionBase* aSVPSession,
+ TMceTransactionDataContainer& aContainer,
+ MSVPTransferObserver& aObserver )
+ {
+ CSVPTransferController* self = new( ELeave ) CSVPTransferController;
+ CleanupStack::PushL( self );
+ self->ConstructL( aMceSession, aSVPSession, aContainer, aObserver );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::~CSVPTransferController
+// ---------------------------------------------------------------------------
+//
+CSVPTransferController::~CSVPTransferController()
+ {
+ delete iTransferContext;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Handle mce event observer notify events.
+// The state of the event has changed.
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::HandleEventStateChangedL(
+ CMceEvent& /* aEvent */,
+ TInt aStatusCode )
+ {
+ if ( KSVPOKVal == aStatusCode )
+ {
+ if ( iTransferContext->IsAttended() )
+ {
+ SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal & attended" );
+ if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState())
+ {
+ // F25 OK received - already acccepted
+ // leave for not to create new session later
+ SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: transfer in progress");
+ User::Leave( KSVPErrTransferInProgress );
+ }
+
+ // F18 OK received as response for "trying"
+ // Set and apply the next state - accepted
+ iTransferContext->SetCurrentStateL( KSVPTransferAcceptedStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL:ApplyCurrentStateL done" );
+ }
+ else // unattended transfer
+ {
+ SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal unattended" );
+ if ( iTransferContext->CheckIsSessionRemoteHold() &&
+ KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() )
+ {
+ // Transferer has put transferee on hold before sending refer
+ SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: Snom or similar as transferer" );
+ SendNotifyL( aStatusCode ); // 200 OK
+ }
+ }
+ }
+ else
+ {
+ SVPDEBUG2("CSVPTransferController::HandleEventStateChangedL: aStatusCode = %d",
+ aStatusCode);
+ }
+ SVPDEBUG1("CSVPTransferController::HandleEventStateChangedL: Out");
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::NotifyReceivedL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::NotifyReceivedL(
+ CMceEvent& aEvent,
+ TMceTransactionDataContainer* aContainer )
+ {
+ SVPDEBUG1("CSVPTransferController::NotifyReceivedL: In");
+
+ // check data container and match the event to the active refer event
+ if ( aContainer && iTransferContext->MceEvent() == &aEvent )
+ {
+ TInt statusCode = aContainer->GetStatusCode();
+ HBufC8* content = aContainer->GetContent();
+
+ SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\
+ statusCode: %d", statusCode );
+ SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\
+ aContainer->GetContent()->Length(): %d", content->Length() );
+
+ if ( !content->Find( TPtrC8( KSVPNotifyTrying ) ) )
+ {
+ if ( iTransferContext->IsAttended() )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\
+ SIP/2.0 100 Trying" );
+
+ // Attended transfer (F17) NOTIFY , transferee is trying establish new session.
+ // Check if 202 Accepted already received
+ if ( iAccepted )
+ {
+ // Stop the refer timer
+ iTransferContext->StopReferTimer( );
+ // Set and apply the next state - accepted
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferAcceptedStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ }
+ }
+ else
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended case:\
+ SIP/2.0 100 Trying" );
+
+ // Check if 202 Accepted already received
+ if ( iAccepted )
+ {
+ // Stop the refer timer
+ iTransferContext->StopReferTimer( );
+
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: is accepted" );
+
+ // Unattended transfer: F7 NOTIFY, display "transferred" note
+ if( iCCPTransferObserver )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
+ iCCPTransferObserver->TransferEventOccurred(
+ MCCPTransferObserver::ECCPLocalTransfer );
+ }
+
+ // Set and apply the next state - accepted
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferAcceptedStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ // Unattended transfer is ok, hangup the session
+ iTransferContext->TransferObserver().TransferNotification(
+ ESVPTransferOKHangUp );
+ }
+ }
+ }
+ else if ( !content->Find( TPtrC8( KSVPNotifyOK ) ) ||
+ !content->Find( TPtrC8( KSVPNotifyOk2 ) ) )
+ {
+ if ( iTransferContext->IsAttended() )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\
+ SIP/2.0 200 OK" );
+
+ // Attended transfer (F24) 200 OK
+ if( iCCPTransferObserver )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
+ iCCPTransferObserver->TransferEventOccurred(
+ MCCPTransferObserver::ECCPLocalTransfer );
+ }
+
+ // Set and apply the next state - terminating
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+
+ // Attended transfer is ok, hangup the session
+ iTransferContext->TransferObserver().TransferNotification(
+ ESVPTransferOKHangUp );
+ }
+ else
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended: SIP/2.0 200 OK" );
+ }
+ }
+ else if ( ( !content->Find( TPtrC8( KSVPNotifyRinging ) ) ||
+ !content->Find( TPtrC8( KSVPNotifyRinging183 ) ) ) &&
+ !iTransferContext->IsAttended())
+ {
+ // Polycom send Ringing instead of Trying in unattended case.
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended and Ringing" );
+
+ // Check if 202 Accepted already received
+ if ( iAccepted )
+ {
+ // Stop the refer timer
+ iTransferContext->StopReferTimer( );
+
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: Polycom case" );
+
+ // Unattended transfer: display "transferred" note
+ if( iCCPTransferObserver )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" );
+ iCCPTransferObserver->TransferEventOccurred(
+ MCCPTransferObserver::ECCPLocalTransfer );
+ }
+
+ // Set and apply the next state - accepted
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferAcceptedStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ // Unattended transfer is ok, hangup the session
+ iTransferContext->TransferObserver().TransferNotification(
+ ESVPTransferOKHangUp );
+ }
+ }
+ else if ( !content->Find( TPtrC8( KSVPNotifyServiceUnavailable ) ) )
+ {
+ // Notify that comes after the accepted refer, if
+ // the (wrong) address of the refer cannot be reached.
+ if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() )
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503 -> ECCPTransferFailed");
+
+ // Set and apply the next state - terminating
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+
+ // Transfer fails, notify client.
+ iTransferContext->TransferObserver().TransferNotification(
+ ESVPTransferDecline );
+ }
+ else
+ {
+ SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503.");
+ }
+ }
+ else
+ {
+ SVPDEBUG1("CSVPTransferController::NotifyReceivedL:\
+ Unhandled container content");
+ }
+
+ // Ownership transferred here
+ delete content;
+ }
+
+ SVPDEBUG1("CSVPTransferController::NotifyReceivedL: Out");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::HandleReferStateChangeL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::HandleReferStateChangeL( CMceRefer& aRefer,
+ TInt aStatusCode )
+ {
+ SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() In");
+
+ if ( iTransferContext->MceRefer() == &aRefer )
+ {
+ if ( KSVPAcceptedVal == aStatusCode )
+ {
+ // Accepted unattended F6, Attended F16
+ SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Accept: %i",
+ KSVPAcceptedVal );
+
+ // Display "transferring" note
+ if( iCCPTransferObserver )
+ {
+ SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL, send remote transferring" );
+ iCCPTransferObserver->TransferEventOccurred(
+ MCCPTransferObserver::ECCPRemoteTransferring );
+ }
+ // Continue acceptance when also notify F7 / F17 "trying" received
+ iAccepted = ETrue;
+ }
+ else if ( ( KSVPBadRequestVal <= aStatusCode &&
+ KSVPRequestPendingVal >= aStatusCode ) ||
+ KSVPDeclineVal == aStatusCode ||
+ KSVPServerInternalErrorVal == aStatusCode ||
+ KSVPPreconditionFailureVal == aStatusCode )
+ {
+ // Decline, Request Failure 4xx or Server Failure 5xx
+ SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Code: %i", aStatusCode );
+ // Stop the refer timer
+ iTransferContext->StopReferTimer( );
+
+ // Set and apply the next state - terminating
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+
+ // Notify the observer about the decline.
+ iTransferContext->TransferObserver().TransferNotification(
+ ESVPTransferDecline );
+ }
+
+ else
+ {
+ // Not handled
+ SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: \
+ Unknown StatusCode: %i", aStatusCode );
+ }
+ }
+ else
+ {
+ // Unknown refer - not handled
+ SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL: \
+ Unknown refer");
+ }
+
+ SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() Out");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::IncomingReferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::IncomingReferL( CMceInRefer* aRefer,
+ const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer )
+ {
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL In" )
+
+ // Is new incoming refer handling possible
+ if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
+ {
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: allowed" )
+
+ iTransferContext->SetMceRefer( static_cast<CMceRefer*>( aRefer ) );
+ iTransferContext->SetIncomingReferToL( aReferTo );
+ CDesC8Array* headers = aContainer->GetHeaders();// get headers
+
+ if ( headers )
+ {
+ TBool found = EFalse;
+
+ for( TInt i = 0; i < headers->MdcaCount() && !found; i++ )
+ {
+ TPtrC8 tmpHeader = headers->MdcaPoint( i );
+
+ if ( KErrNotFound != tmpHeader.FindF( KSVPReferredBy ) )
+ {
+ SVPDEBUG1( "KSVPReferredBy found" )
+ found = ETrue;
+ iTransferContext->SetIncomingReferredByL( tmpHeader );
+ }
+ }
+ }
+
+ delete headers;
+ headers = NULL;
+ }
+
+ else if ( KSVPTransferPendingStateIndex == iTransferContext->CurrentState() )
+ {
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed \
+ -> ignore" )
+ User::Leave( KSVPErrTransferInProgress );
+ }
+
+ else
+ {
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed" )
+ User::Leave( KSVPErrTransferStateError );
+ }
+
+ if ( iTransferContext->IsAttended() )
+ {
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: Attended case, send accept" )
+
+ // send trying notification and wait respond for it
+ CMceInEvent* inEvent = NULL;
+
+ TRAPD( acceptError, inEvent = static_cast<CMceInRefer*>(
+ iTransferContext->MceRefer() )->AcceptL() );
+
+ if ( KErrNone == acceptError )
+ {
+ // Apply state, changes to next state (pending)
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: pending state" )
+ iTransferContext->SetMceEvent( static_cast<CMceEvent*>( inEvent ) );
+ iTransferContext->ApplyCurrentStateL();
+ }
+ else
+ {
+ // Set and apply the next state - terminating
+ SVPDEBUG2("CSVPTransferController::IncomingReferL: acc fails = %d", acceptError )
+ iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ }
+ }
+ else
+ {
+ // Apply state, changes to next state (pending)
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL: UnAttended case pending" )
+ iTransferContext->ApplyCurrentStateL();
+ }
+
+ SVPDEBUG1( "CSVPTransferController::IncomingReferL Out" )
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::IsMceRefer
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferController::IsMceRefer( CMceRefer& aRefer )
+ {
+ return ( iTransferContext->MceRefer() == &aRefer );
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::IsAttended
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferController::IsAttended( )
+ {
+ return ( iTransferContext->IsAttended() );
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::SetTransferDataL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::SetTransferDataL( CDesC8Array* aUserAgentHeaders,
+ TInt aSecureStatus )
+ {
+ SVPDEBUG1(" CSVPTransferController::SetTransferDataL" );
+ iTransferContext->SetTransferDataL( aUserAgentHeaders, aSecureStatus );
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::SetMceSessionObject
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::SetMceSessionObject( CMceSession* aSession )
+ {
+ iTransferContext->SetMceSessionObject( aSession );
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::SendNotifyL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::SendNotifyL( TInt aStatusCode )
+ {
+ SVPDEBUG2("CSVPTransferController::SendNotifyL() code = %d", aStatusCode);
+
+ CMceInEvent* inEvent = static_cast< CMceInEvent* > (
+ iTransferContext->MceEvent());
+ if (inEvent)
+ {
+ HBufC8* contentType = KSVPMessageSipfrag().AllocLC(); //message/sipfrag
+ HBufC8* content = NULL;
+
+ if (KSVPOKVal == aStatusCode )
+ {
+ content = KSVPNotifyOK().AllocLC(); // "SIP/2.0 200 OK"
+ }
+ else if ( KSVPNotFoundVal == aStatusCode ||
+ KSVPBusyHereVal == aStatusCode ||
+ KSVPDeclineVal == aStatusCode )
+ {
+ content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
+ }
+ else
+ {
+ SVPDEBUG2("CSVPTransferController::SendNotifyL unknown aStatusCode = %d", aStatusCode);
+ content = KSVPNotifyServiceUnavailable().AllocLC(); // "503"
+ }
+
+ CDesC8Array* headers = NULL;
+ headers = new( ELeave ) CDesC8ArrayFlat( KSVPContactArrayGranularity );
+ CleanupStack::PushL( headers );
+ headers->AppendL( KSVPSubsStateTerminated );
+
+ // Notify is sent to transferer (unattended msg F15, attended msg F24)
+ TRAPD( errNotify, inEvent->TerminateL( headers, contentType, content ) );
+
+ if ( KErrNone == errNotify )
+ {
+ SVPDEBUG1("CSVPTransferController::SendNotifyL, notify sending OK");
+ CleanupStack::Pop( 3, contentType ); // headers, content, contentType
+ }
+ else
+ {
+ // error handling
+ SVPDEBUG2("CSVPTransferController::SendNotifyL: errNotify = %d", errNotify );
+ CleanupStack::PopAndDestroy( 3, contentType ); // headers, content, contentType
+ }
+ }
+
+ if ( iTransferContext->IsAttended() )
+ {
+ SVPDEBUG1("CSVPTransferController::SendNotifyL() Attended done");
+ }
+ else
+ {
+ SVPDEBUG1("CSVPTransferController::SendNotifyL() UnAttended to terminating state");
+ // Finish unattended incoming transfer sequence
+ // Set and apply the next state - terminating
+ iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ }
+
+ SVPDEBUG1("CSVPTransferController::SendNotifyL() Out");
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::IsIncomingTransfer
+// ---------------------------------------------------------------------------
+//
+TBool CSVPTransferController::IsIncomingTransfer()
+ {
+ SVPDEBUG2("CSVPTransferController::IsIncomingTransfer = %d",
+ iTransferContext->IsIncoming() );
+ return iTransferContext->IsIncoming();
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::TerminateTransfer
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::TerminateTransfer()
+ {
+ SVPDEBUG1("CSVPTransferController::TerminateTransfer" )
+ TRAP_IGNORE( TerminateTransferL() );
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::TerminateTransferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::TerminateTransferL()
+ {
+ iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::AttendedTransfer
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferController::AttendedTransfer( MCCPCall& aTransferTargetCall )
+ {
+ SVPDEBUG1( "CSVPTransferController::AttendedTransfer call IN" );
+ TRAPD( transError, TransferL( &aTransferTargetCall, KNullDesC, ETrue ));
+ SVPDEBUG2( "CSVPTransferController::AttendedTransfer A return: %d", transError );
+ return transError;
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::AttendedTransfer
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferController::AttendedTransfer( const TDesC& aTransferTarget )
+ {
+ SVPDEBUG1( "CSVPTransferController::AttendedTransfer target IN" );
+ TRAPD( transError, TransferL( NULL, aTransferTarget, ETrue ));
+ SVPDEBUG2( "CSVPTransferController::AttendedTransfer B return: %d", transError );
+ return transError;
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::UnattendedTransfer
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferController::UnattendedTransfer( const TDesC& aTransferTarget )
+ {
+ SVPDEBUG1( "CSVPTransferController::UnattendedTransfer IN" );
+ TRAPD( transError, TransferL( NULL, aTransferTarget, EFalse ));
+ SVPDEBUG2( "CSVPTransferController::UnattendedTransfer return: %d", transError );
+ return transError;
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::AcceptTransfer
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferController::AcceptTransfer( const TBool aAccept )
+ {
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer() IN aAccept = \
+ %d", aAccept);
+ TInt acceptError = KErrNone;
+ TInt stateError = KErrNone;
+ TInt currentState = iTransferContext->CurrentState();
+ CMceInEvent* inEvent(NULL);
+
+ // Is state "pending"
+ if ( KSVPTransferPendingStateIndex == currentState )
+ {
+ if ( aAccept )
+ {
+ TRAP( acceptError, ( inEvent = static_cast< CMceInRefer* > (iTransferContext->MceRefer())->AcceptL()));
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
+ AcceptL = %d", acceptError);
+ }
+ else
+ {
+ SVPDEBUG1("CSVPTransferController::AcceptTransfer() reject");
+ TRAP( acceptError, ( static_cast< CMceInRefer* > (iTransferContext->MceRefer())->RejectL()) );
+ }
+
+ if ( KErrNone == acceptError )
+ {
+ if ( aAccept )
+ {
+ // Set the received event
+ iTransferContext->SetMceEvent(static_cast< CMceEvent* >(inEvent));
+
+ // Set and apply the next state - accepted
+ TRAP( acceptError,
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferAcceptedStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ );
+ }
+ else
+ {
+ // Set and apply the next state - terminating
+ TRAP( acceptError,
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ );
+ }
+ }
+ else
+ {
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
+ fails = %d", acceptError);
+ // Set and apply the next state - terminating
+ TRAP( stateError,
+ iTransferContext->SetCurrentStateL(
+ KSVPTransferTerminatingStateIndex );
+ iTransferContext->ApplyCurrentStateL();
+ );
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
+ stateError = %d", stateError);
+ }
+ }
+ else
+ {
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
+ current state is not pending: %d", currentState);
+ acceptError = KSVPErrTransferStateError;
+ }
+
+ SVPDEBUG2("CSVPTransferController::AcceptTransfer()\
+ OUT acceptError = %d", acceptError);
+ return acceptError;
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::TransferTarget
+// ---------------------------------------------------------------------------
+//
+const TDesC& CSVPTransferController::TransferTarget() const
+ {
+ return iTransferContext->IncomingReferTo();
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::AddObserverL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::AddObserverL(
+ const MCCPTransferObserver& aObserver )
+ {
+ SVPDEBUG1("CSVPTransferController::AddObserverL() In");
+ // set transfer observer
+ // only one observer used at a time, replaces current one
+ iCCPTransferObserver = const_cast<MCCPTransferObserver*>(&aObserver);
+
+ SVPDEBUG1("CSVPTransferController::AddObserverL() Out");
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::RemoveObserver
+// ---------------------------------------------------------------------------
+//
+TInt CSVPTransferController::RemoveObserver(
+ const MCCPTransferObserver& aObserver )
+ {
+ SVPDEBUG1("CSVPTransferController::RemoveObserver");
+ TInt err = KErrNone;
+ if ( iCCPTransferObserver == const_cast<MCCPTransferObserver*>
+ (&aObserver) )
+ {
+ iCCPTransferObserver = NULL;
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// CSVPTransferController::TransferL
+// ---------------------------------------------------------------------------
+//
+void CSVPTransferController::TransferL( MCCPCall* aCall,
+ const TDesC& aTarget,
+ const TBool aAttendedTransfer )
+ {
+ SVPDEBUG1("CSVPTransferController::TransferL() In");
+
+ // Transfer possible.
+ if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() )
+ {
+ iAccepted = EFalse;
+
+ // Set transfer parameters
+ iTransferContext->SetTransferParmsL(
+ static_cast< CSVPSessionBase* >(aCall),
+ aTarget,
+ aAttendedTransfer );
+
+ // Apply state, execute the refer and change to next state (pending).
+ iTransferContext->ApplyCurrentStateL();
+ }
+ else
+ {
+ SVPDEBUG1( "CSVPTransferController::TransferL: Error - transfer in progress" );
+ iTransferContext->TransferObserver().TransferFailed( KErrInUse );
+ TerminateTransferL();
+ }
+
+ SVPDEBUG1("CSVPTransferController::TransferL() OUT");
+ }
+
+