diff -r f742655b05bf -r d38647835c2e callcontinuity/vcc/src/cvccperformer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/callcontinuity/vcc/src/cvccperformer.cpp Wed Sep 01 12:29:57 2010 +0100 @@ -0,0 +1,988 @@ +/* +* Copyright (c) 2008 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: CCP reference plug-in implementation. +* +*/ + +#include +#include +#include "ccpdefs.h" +#include + +#include "vccdefinitions.h" +#include "cvccperformer.h" +#include "vcchotrigger.h" +#include "vccsettingsreader.h" +#include "cvcctransferprovider.h" + +//state machine +#include "tvccstateinit.h" +#include "tvccstatecalling.h" +#include "tvccstatefailing.h" +#include "tvccstatereleasing.h" +#include "rubydebug.h" + +_LIT( KSVPSipPrefix, "sip:" ); +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CVccPerformer::CVccPerformer(RPointerArray& aProviders, + TVccState& aState, CVccHoTrigger& aVccHoTrigger, + TBool aCsOriginated ) : + iProviders(aProviders), + iCurrentState(&aState), + iVccHoTrigger( aVccHoTrigger ), + iCsOriginated( aCsOriginated), + iTransferProvider( NULL ), + iRemotePartiesSet( EFalse ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CVccPerformer" ); + } + +// ----------------------------------------------------------------------------- +// Default C++ destructor. +// ----------------------------------------------------------------------------- +// +CVccPerformer::~CVccPerformer() + { + RUBY_DEBUG0( "CVccPerformer::~CVccPerformer() - ENTER" ); + delete iVccPsp; + delete iTransferProvider; + RUBY_DEBUG0( "CVccPerformer::~CVccPerformer() - EXIT" ); + } +// ----------------------------------------------------------------------------- +// Call creating comes here. In MT case observer is null and CCE will call +// SetObserver later on for us +// ----------------------------------------------------------------------------- +// +CVccPerformer* CVccPerformer::NewL( + RPointerArray& aProviders, + TVccState& aState, + CVccHoTrigger& aVccHoTrigger, + TBool aCsOriginated) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::NewL" ); + CVccPerformer* self = new( ELeave ) CVccPerformer(aProviders, + aState, + aVccHoTrigger, + aCsOriginated); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ConstructL() + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::ConstructL" ); + + iVccPsp = CVccEngPsProperty::NewL(); + } + +// ----------------------------------------------------------------------------- +// User has answered the incoming call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Answer() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Answer" ); + return iCurrentState->Answer(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// User has rejected the incoming call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Reject() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Reject" ); + return iCurrentState->Reject(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Queue incoming call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Queue() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Queue" ); + return iCurrentState->Queue(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Dial a new call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Dial() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Dial" ); + return iCurrentState->Dial(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// MT call user ringing now +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Ringing() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Ringing" ); + return iCurrentState->Ringing(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// End current call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::HangUp() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::HangUp" ); + return iCurrentState->HangUp(*this, *iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Cancel ongoing request +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Cancel() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Cancel" ); + return iCurrentState->Cancel(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Hold call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Hold() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Hold" ); + return iCurrentState->Hold(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Resume held call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Resume() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Resume" ); + return iCurrentState->Resume(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Swap hold/resume states +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Swap() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Swap" ); + return iCurrentState->Swap(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Get call recipient +// ----------------------------------------------------------------------------- +// +const TDesC& CVccPerformer::RemoteParty() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::RemoteParty" ); + + return iOrigRemoteParty; + } + +// ----------------------------------------------------------------------------- +// RemotePartyName +// ----------------------------------------------------------------------------- +// +const TDesC& CVccPerformer::RemotePartyName() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::RemotePartyName" ); + return iOrigRemotePartyName; + //return iCurrentState->RemoteParty(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Get call recipient +// ----------------------------------------------------------------------------- +// +const TDesC& CVccPerformer::DialledParty() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::DialledParty" ); + return iCurrentState->DialledParty(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Is call forwarded or not +// ----------------------------------------------------------------------------- +// +TBool CVccPerformer::IsCallForwarded() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::IsCallForwarded " ); + return iCurrentState->IsCallForwarded(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Is call mobile originated or not +// ----------------------------------------------------------------------------- +// +TBool CVccPerformer::IsMobileOriginated() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::IsMobileOriginated" ); + return iCurrentState->IsMobileOriginated(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Get current call state +// ----------------------------------------------------------------------------- +// +MCCPCallObserver::TCCPCallState CVccPerformer::State() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::State " ); + return iCurrentState->State(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Get plug-in UID +// ----------------------------------------------------------------------------- +// +TUid CVccPerformer::Uid() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Uid " ); + + return TUid::Uid( KVccCallProviderPlugId ); + } + +// ----------------------------------------------------------------------------- +// get call capabilities +// ----------------------------------------------------------------------------- +// +MCCPCallObserver::TCCPCallControlCaps CVccPerformer::Caps() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CVccPerformer" ); + return iCurrentState->Caps(*iPrimaryCall); + } + + +// ----------------------------------------------------------------------------- +// SecureSpecified() +// ----------------------------------------------------------------------------- +// +TBool CVccPerformer::SecureSpecified() const + { + return iCurrentState->SecureSpecified( *iPrimaryCall ); + } +// ----------------------------------------------------------------------------- +// Is call secured +// ----------------------------------------------------------------------------- +// +TBool CVccPerformer::IsSecured() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::IsSecured" ); + return iCurrentState->IsSecured(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Set parameters +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SetParameters( const CCCPCallParameters& aNewParams ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::SetParameters " ); + iCurrentState->SetParameters(aNewParams); + } + +// ----------------------------------------------------------------------------- +// Get parameters +// ----------------------------------------------------------------------------- +// +const CCCPCallParameters& CVccPerformer::Parameters() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Parameters" ); + return iCurrentState->Parameters(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Return used tone. +// ----------------------------------------------------------------------------- +// +TCCPTone CVccPerformer::Tone() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Tone " ); + return iCurrentState->Tone(*iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Get forward call enabling methods for the call +// ----------------------------------------------------------------------------- +// +MCCPForwardProvider* CVccPerformer::ForwardProviderL + ( const MCCPForwardObserver& aObserver ) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::ForwardProviderL " ); + return iPrimaryCall->ForwardProviderL(aObserver); + } + +// ----------------------------------------------------------------------------- +// Get transfer call enabling methods for the call +// ----------------------------------------------------------------------------- +// +MCCPTransferProvider* CVccPerformer::TransferProviderL + ( const MCCPTransferObserver& aObserver ) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::TransferProviderL " ); + if ( !iTransferProvider ) + { + iTransferProvider = CVccTransferProvider::NewL(this); + iTransferProvider->AddObserverL( aObserver ); + } + + return iTransferProvider; + } + +// ----------------------------------------------------------------------------- +// Add observer. +// the CCE will call that in the MT call case, to put the observer for a call in place +// ----------------------------------------------------------------------------- +// +void CVccPerformer::AddObserverL( const MCCPCallObserver& aObserver ) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::AddObserverL " ); + iCallObs = const_cast( &aObserver ); + iCurrentState->AddObserverL(*this, *iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// remove observer. +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::RemoveObserver(const MCCPCallObserver& aObserver ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::RemoveObserver " ); + return iCurrentState->RemoveObserver(aObserver, *iPrimaryCall); + } + +// ----------------------------------------------------------------------------- +// Dial from MCCPCSCall +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::Dial( const TDesC8& aCallParams ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Dial" ); + return iCurrentState->Dial(aCallParams, + *static_cast(iPrimaryCall)); + } + +// ----------------------------------------------------------------------------- +// NoFDNCheck from MCCPCSCall +// ----------------------------------------------------------------------------- +// +void CVccPerformer::NoFDNCheck() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::NoFDNCheck " ); + iCurrentState->NoFDNCheck(*static_cast(iPrimaryCall)); + } + +// ----------------------------------------------------------------------------- +// GetMobileCallInfo from MCCPCSCall +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::GetMobileCallInfo( TDes8& aCallInfo ) const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::GetMobileCallInfo " ); + return iCurrentState->GetMobileCallInfo(aCallInfo, + *static_cast(iPrimaryCall)); + } + +// ----------------------------------------------------------------------------- +// SwitchAlternatingCall from MCCPCSCall +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::SwitchAlternatingCall() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::SwitchAlternatingCall " ); + return iCurrentState->SwitchAlternatingCall( + *static_cast(iPrimaryCall)); + } + +// ----------------------------------------------------------------------------- +// GetMobileDataCallCaps from MCCPCSCall +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::GetMobileDataCallCaps( TDes8& aCaps ) const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::GetMobileDataCallCaps " ); + return iCurrentState->GetMobileDataCallCaps(aCaps, + *static_cast(iPrimaryCall)); + } + +// ----------------------------------------------------------------------------- +// LogDialedNumber from MCCPCSCall +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::LogDialedNumber() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::LogDialedNumber " ); + return iCurrentState->LogDialedNumber( + *static_cast(iPrimaryCall) ); + } + +// ----------------------------------------------------------------------------- +// MCCPCallObserver:: ErrorOccurred +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ErrorOccurred(const TCCPError aError, MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::TCCPError "); + iCurrentState->ErrorOccurred(*this, aError, aCall ); + } + +// ----------------------------------------------------------------------------- +// MCCPCallObserver:: CallStateChanged +// ----------------------------------------------------------------------------- +// +void CVccPerformer::CallStateChanged( + const MCCPCallObserver::TCCPCallState aState, + MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CallStateChanged "); + iCurrentState->CallStateChanged( *this, aState, aCall ); + } + +// ----------------------------------------------------------------------------- +// MCCPCallObserver:: CallStateChangedWithInband +// ----------------------------------------------------------------------------- +// +void CVccPerformer::CallStateChangedWithInband( + const MCCPCallObserver::TCCPCallState aState, + MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CallStateChanged "); + iCurrentState->CallStateChangedWithInband( *this, aState, aCall ); + } + +// ----------------------------------------------------------------------------- +// MCCPCallObserver::CallEventOccurred +// ----------------------------------------------------------------------------- +// +void CVccPerformer::CallEventOccurred( + const MCCPCallObserver::TCCPCallEvent aEvent, + MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CallEventOccurred "); + iCurrentState->CallEventOccurred(*this, aEvent, aCall); + } + +// ----------------------------------------------------------------------------- +// MCCPCallObserver::CallCapsChanged +// ----------------------------------------------------------------------------- +// +void CVccPerformer::CallCapsChanged(const TUint32 aCapsFlags, MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CallCapsChanged"); + iCurrentState->CallCapsChanged(*this, aCapsFlags, aCall ); + } + +// ----------------------------------------------------------------------------- +// Get CallObserver() +// ----------------------------------------------------------------------------- +// +MCCPCallObserver* CVccPerformer::CallObserver() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CallObserver " ); + return iCallObs; + } + +// ----------------------------------------------------------------------------- +// Creates actual implementation +// ----------------------------------------------------------------------------- +// +MCCPCall* CVccPerformer::CreatePrimaryCallL( + const CCCPCallParameters& aParameters, + const TDesC& aRecipient, + const MCCPCallObserver& aObserver ) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::CreatePrimaryCallL" ); + + iPrimaryCall = NULL; + TInt index = KErrNotFound; + if (aParameters.CallType() != CCPCall::ECallTypePS ) + { + index = VoipProviderIndex( EFalse ); + } + else + { + index = VoipProviderIndex( ETrue ); + } + if( index != KErrNotFound ) + { + iPrimaryCall = iProviders[ index ]->NewCallL(aParameters, aRecipient, *this); + } + + if( !iPrimaryCall ) + { + User::Leave( KErrNotFound ); + } + iCallObs = const_cast< MCCPCallObserver* >( &aObserver ); + + SetRemoteParties(); + + return this; + } + +// ----------------------------------------------------------------------------- +// saves incoming call and returns itself +// ----------------------------------------------------------------------------- +// +MCCPCall* CVccPerformer::IncomingCall( MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::IncomingCall" ); + iPrimaryCall = aCall; + SetRemoteParties(); + + return this; + } + +// ----------------------------------------------------------------------------- +// saves 3rd party mo call and returns itself +// ----------------------------------------------------------------------------- +// +MCCPCall* CVccPerformer::MoCall( MCCPCall* aCall ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::MoCall" ); + iPrimaryCall = aCall; + return this; + } + +// ----------------------------------------------------------------------------- +// Returns actual call implementation +// ----------------------------------------------------------------------------- +// +MCCPCall* CVccPerformer::PrimaryCall() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::PrimaryCall" ); + return iPrimaryCall; + } + +// ----------------------------------------------------------------------------- +// Returns actual CS provider implementation +// ----------------------------------------------------------------------------- +// +CConvergedCallProvider& CVccPerformer::CsProvider() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::CsProvider" ); + return *iProviders[ VoipProviderIndex( EFalse ) ]; + + } + +// ----------------------------------------------------------------------------- +// Returns actual PS provider implementation +// ----------------------------------------------------------------------------- +// +CConvergedCallProvider& CVccPerformer::PsProvider() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::PsProvider" ); + return *iProviders[ VoipProviderIndex( ETrue ) ]; + } + +// ----------------------------------------------------------------------------- +// Updates the actual call +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SetCall(MCCPCall* aCall) + { + TRAP_IGNORE( SetCallL( aCall) ); + } + + +// ----------------------------------------------------------------------------- +// Updates the actual call +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SetCallL(MCCPCall* aCall) + { + __ASSERT_DEBUG(aCall == iSecondaryCall, User::Leave(KErrArgument)); + RUBY_DEBUG_BLOCK( "CVccPerformer::SetCall" ); + + //inform through phone engine to phone about call bubble update needs + MCCPCallObserver::TCCPCallEvent event = + MCCPCallObserver::ECCPNotifyRemotePartyInfoChange; + iCallObs->CallEventOccurred( event, this ); + + //both secure call and not secure call events result in same + //securestatuschanged message in phone engine. + + + MCCPCall* temp = iPrimaryCall; + iPrimaryCall = aCall; + iSecondaryCall = temp; //taking old call pointer + if (iTransferProvider) + { + iTransferProvider->UpdateL(); + } + + MCCPCallObserver::TCCPCallEvent event2; + //if( iPrimaryCall->IsSecured() ) + // { + // event2 = MCCPCallObserver::ECCPSecureCall; + // } + //else + // { + event2 = MCCPCallObserver::ECCPNotSecureCall; + // } + iCallObs->CallEventOccurred( event2, this ); + + } + +// ----------------------------------------------------------------------------- +// Releases ongoing call +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::ReleaseCall(MCCPCall& /*aCall*/) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::ReleaseCall" ); + TInt err = KErrNotFound; + err = iCurrentState->ReleaseCall(*iPrimaryCall, iProviders); + iPrimaryCall = NULL; + return err; + } + +// ----------------------------------------------------------------------------- +// Suppressor calls this when HO is done +// ----------------------------------------------------------------------------- +// +void CVccPerformer::HandoverReady() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::HandoverReady" ); + iSecondaryCall = NULL; + ActivateTrigger( ETrue ); + //get new service id for voip call and set it to parameters + //this is used later for loading correct CTI plugins + TInt VoIPServiceId(KErrNotFound); + TRAP_IGNORE( VoIPServiceId = VccSettingsReader::VoIPServiceIdL() ); + RUBY_DEBUG1( "CVccPerformer::HandoverReady() -- new Service Id: %d", VoIPServiceId ); + CCCPCallParameters* params = NULL; + TRAP_IGNORE( params = iPrimaryCall->Parameters().CloneL() ); + params->SetServiceId( VoIPServiceId ); + iPrimaryCall->SetParameters( *params ); + //inform through phone engine to phone about call bubble update needs + MCCPCallObserver::TCCPCallEvent event = + MCCPCallObserver::ECCPNotifyRemotePartyInfoChange; + iCallObs->CallEventOccurred( event, this ); + + RUBY_DEBUG0("Let HoTrigger know about changed domain"); + + if( params->CallType() == CCPCall::ECallTypeCSVoice ) + { + RUBY_DEBUG0("New domain is CS"); + iVccHoTrigger.SetCurrentDomainType( CVccHoTrigger::ECallDomainTypeCS ); + } + else + { + RUBY_DEBUG0("New domain is PS"); + iVccHoTrigger.SetCurrentDomainType( CVccHoTrigger::ECallDomainTypePS ); + } + + delete params; + } + +// ----------------------------------------------------------------------------- +// Creates a new call to be handled +// ----------------------------------------------------------------------------- +// +void CVccPerformer::CreateSecondaryCallL( + const CCCPCallParameters& aParameters, + const TDesC& aRecipient, + const MCCPCallObserver& aObserver) + { + RUBY_DEBUG_BLOCKL( "CVccPerformer::CreateLocalSecondaryCallL" ); + iSecondaryCall = NULL; + TInt index = KErrNotFound; + if (aParameters.CallType() != CCPCall::ECallTypePS ) + { + index = VoipProviderIndex( EFalse ); + } + else + { + index = VoipProviderIndex( ETrue ); + } + if( index != KErrNotFound ) + { + iSecondaryCall = iProviders[ index ]->NewCallL(aParameters, + aRecipient, + aObserver); + } + + if( !iSecondaryCall ) + { + User::Leave( KErrNotFound ); + } + } + +// ----------------------------------------------------------------------------- +// Creates a new call to be handled +// ----------------------------------------------------------------------------- +// +MCCPCall* CVccPerformer::SecondaryCall() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::SecondaryCall" ); + return iSecondaryCall; + } + +// ----------------------------------------------------------------------------- +// Updates the state with the next one +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SetState(TVccState& aState) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::SetState" ); + iCurrentState = &aState; + } + +// ----------------------------------------------------------------------------- +// Returns the state name +// ----------------------------------------------------------------------------- +// +TUint CVccPerformer::StateName() const + { + RUBY_DEBUG_BLOCK( "CVccPerformer::StateName" ); + return iCurrentState->Name(); + } + +// ----------------------------------------------------------------------------- +// Returns the Notifier +// ----------------------------------------------------------------------------- +// +CVccEngPsProperty& CVccPerformer::Notifier() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::Notifier" ); + return *iVccPsp; + } + +// ----------------------------------------------------------------------------- +// Starts Handover procedure +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SwitchL( const TInt aValue ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::DoHandover" ); + //there must be an actuall call implementation created + __ASSERT_DEBUG(iPrimaryCall != NULL, User::Leave(KErrArgument)); + + //dont change remote party after/during handover + iRemotePartiesSet = ETrue; + // check which call is active and do handover for that call. other calls + // are dropped. + if( iPrimaryCall->State() == MCCPCallObserver::ECCPStateConnected ) + { + switch ( iPrimaryCall->Parameters().CallType() ) + { + case CCPCall::ECallTypeCSVoice: + { + // CS call active + if ( aValue == EVccAutomaticStartCsToPsHoRequest || + aValue == EVccManualStartCsToPsHoRequest || + aValue == EVccAutomaticStartCsToPsHoRequestIfSingleCall ) + { + // HO direction OK + RUBY_DEBUG0( "- CS to PS HO OK" ); + iCurrentState->SwitchL(*this); + } + break; + } + case CCPCall::ECallTypePS: + { + // PS call active + if ( aValue == EVccAutomaticStartPsToCsHoRequest || + aValue == EVccManualStartPsToCsHoRequest || + aValue == EVccAutomaticStartPsToCsHoRequestIfSingleCall ) + { + // HO direction OK + RUBY_DEBUG0( "- PS to CS HO OK" ); + iCurrentState->SwitchL(*this); + } + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// Activates trigger when call becomes active +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ActivateTrigger( TBool aActivation ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::ActivateTrigger" ); + //Dont activate trigger if ho not allowed + if( aActivation ) + { + // Trigger is started only if call type is CS or PS + CCPCall::TCallType type = iPrimaryCall->Parameters().CallType(); + if ( type == CCPCall::ECallTypeCSVoice || + type == CCPCall::ECallTypePS ) + { + //call became active, start trigger for automatic HOs + //inform trigger about the original domain so it can check + //possible HO restrictions + iVccHoTrigger.Start( *this, iCsOriginated ); + } + } + else + { + //call is not active anymore, stop trigger + iVccHoTrigger.Stop( *this ); + } + } + +// ----------------------------------------------------------------------------- +// Updates PS key using trigger +// ----------------------------------------------------------------------------- +// +void CVccPerformer::AllowHo( TBool aAllow ) + { + TRAP_IGNORE( AllowHoL( aAllow) ); + } + +// ----------------------------------------------------------------------------- +// Updates PS key using trigger +// ----------------------------------------------------------------------------- +// +void CVccPerformer::AllowHoL( TBool aAllow ) + { + RUBY_DEBUG_BLOCK( "CVccPerformer::AllowHoL" ); + if( aAllow ) + { + //HO is allowed, item can be in in call options menu + iVccHoTrigger.HoAllowed(); + } + else + { + //HO is not allowed (f.ex. remote hold) and UI item needs to be removed + iVccHoTrigger.HoNotAllowedL(); + } + } + +// ----------------------------------------------------------------------------- +// Checks call state and starts trigger if connected +// Conference call doesnt notify state Connected after conference ended +// Only one call can be in Connected state +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ConferenceEnded() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::ConferenceEnded" ); + if( iPrimaryCall->State() == MCCPCallObserver::ECCPStateConnected ) + { + ActivateTrigger( ETrue ); + } + } + +// ----------------------------------------------------------------------------- +// Release secondary call leg, if needed, before calling destructor +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ReleaseSecondaryCallLeg() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::ReleaseSecondaryCallLeg" ); + if ( iSecondaryCall ) + { + TInt err = iCurrentState->ReleaseCall(*iSecondaryCall, iProviders); + if( err != KErrNone ) + { + RUBY_DEBUG0("CVccPerformer::ReleaseSecondaryCallLeg:" ); + RUBY_DEBUG1("Error releasing secondary call leg: %d", err ); + } + } + } + +// ----------------------------------------------------------------------------- +// Save original RemoteParty and RemotePartyName +// ----------------------------------------------------------------------------- +// +void CVccPerformer::SetRemoteParties() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::SetRemoteParties" ); + if( !iRemotePartiesSet ) + { + iOrigRemoteParty = iPrimaryCall->RemoteParty(); + iOrigRemotePartyName = iPrimaryCall->RemotePartyName(); + ParseRemoteParty(); + } + } + +// ----------------------------------------------------------------------------- +// Return ps/cs provider index +// ----------------------------------------------------------------------------- +// +TInt CVccPerformer::VoipProviderIndex( TBool aVoipIndexWanted ) + { + TInt index = KErrNotFound; + CSInfo info; + if( aVoipIndexWanted ) + { + for( TInt i = 0; i < iProviders.Count(); i++ ) + { + if( !iProviders[ i ]->GetCSInfo( info ) ) + { + index = i; + break; + } + } + } + else + { + for( TInt i = 0; i < iProviders.Count(); i++ ) + { + if( iProviders[ i ]->GetCSInfo( info ) ) + { + index = i; + break; + } + } + } + return index; + } + +// ----------------------------------------------------------------------------- +// Parse remoteparty number if call is VoIP call +// ----------------------------------------------------------------------------- +// +void CVccPerformer::ParseRemoteParty() + { + RUBY_DEBUG_BLOCK( "CVccPerformer::ParseRemoteParty" ); + TInt position = 0; + + // seek '@' sign (returns KErrNotFound if none) + position = iOrigRemoteParty.Locate('@'); + + // if found + if(position != KErrNotFound) + { + TInt length = iOrigRemoteParty.Length(); + // remove the domain part from sip uri + iOrigRemoteParty.Delete(position, length - position); + //and delete 'sip:' prefix if found + if ( iOrigRemoteParty.Find( KSVPSipPrefix ) != KErrNotFound ) + { + RUBY_DEBUG0("SIP: prefix found, delete it"); + iOrigRemoteParty.Delete(0, 4); + } + } + + }