diff -r 7b872347d83b -r 6d0b9f605b61 sipvoipprovider/src/svpcontroller.cpp --- a/sipvoipprovider/src/svpcontroller.cpp Tue Feb 02 00:05:57 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3510 +0,0 @@ -/* -* Copyright (c) 2006-2009 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: Handles all common logic for SVP and handles sessions. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include // CWlanMgmtClient -#include - -#include "svpcontroller.h" -#include "svpmosession.h" -#include "svpmtsession.h" -#include "svplogger.h" -#include "svptimer.h" -#include "svputility.h" -#include "svpholdcontext.h" -#include "svpholdcontroller.h" -#include "svpcleanupresetanddestroy.h" -#include "svpaudioutility.h" -#include "svpsipconsts.h" -#include "svpemergencyiapprovider.h" -#include "svprtpobserver.h" -#include "svpsettings.h" - -// --------------------------------------------------------------------------- -// CSVPController::CSVPController -// --------------------------------------------------------------------------- -// -CSVPController::CSVPController() : iSessionUpdateOngoing( EFalse ) - { - - } - -// --------------------------------------------------------------------------- -// CSVPController::ConstructL -// --------------------------------------------------------------------------- -// -void CSVPController::ConstructL() - { - SVPDEBUG1( "CSVPController::ConstructL In" ) - - iIncomingReferCallIndex = KErrNotFound; - iHoldCallIndex = KErrNotFound; - iSuppServices = CSVPSupplementaryServices::NewL(); - iSVPUtility = CSVPUtility::NewL(); - iRtpObserver = CSVPRtpObserver::NewL(); -#ifndef __WINS__ - iWlanMgmt = CWlanMgmtClient::NewL(); -#endif // __WINS__ - - SVPDEBUG1( "CSVPController::ConstructL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::NewL -// --------------------------------------------------------------------------- -// -CSVPController* CSVPController::NewL() - { - CSVPController* self = new ( ELeave ) CSVPController(); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// --------------------------------------------------------------------------- -// CSVPController::~CSVPController -// --------------------------------------------------------------------------- -// -CSVPController::~CSVPController() - { - SVPDEBUG1( "CSVPController::~CSVPController In" ) - -#ifndef __WINS__ - delete iWlanMgmt; -#endif // __WINS__ - - delete iSVPUtility; - - // clean array that contains SVP sessions. - iSessionArray.ResetAndDestroy(); - iSessionArray.Close(); - - // SVP emergency session - delete iEmergencySession; - - iEmergencyProfileIds.Close(); - iEmergencyIapIds.Close(); - - delete iSuppServices; - delete iMceManager; - delete iRtpObserver; - - delete iDtmfString; - - SVPDEBUG1( "CSVPController::~CSVPController Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::InitializeL -// --------------------------------------------------------------------------- -// -void CSVPController::InitializeL( const TUint32 aServiceId, - const MCCPObserver& aMonitor, - const MCCPSsObserver& aSsObserver ) - { - - SVPDEBUG2( "CSVPController::InitializeL serviceId = %d", aServiceId ) - - SVPDEBUG2( "CSVPController::InitializeL iCCPMonitor: 0x%x", iCCPMonitor ) - - //Find callprovider plugin uid that should be used when registering to MCE - TInt ccpUid = SvpSettings::IntPropertyL( aServiceId, - EPropertyCallProviderPluginId ); - SVPDEBUG2( "CSVPController::InitializeL callproviderpluginuid=%d", ccpUid ) - - // See CConvergedCallProvider API documentation. If already called, - // leave with KErrAlreadyExists. - __ASSERT_ALWAYS( !iCCPMonitor, User::Leave( KErrAlreadyExists ) ); - __ASSERT_ALWAYS( !iCCPSsObserver, User::Leave( KErrAlreadyExists ) ); - __ASSERT_ALWAYS( iSVPUtility, User::Leave( KErrNotReady ) ); - __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrNotReady ) ); - - // save CCP monitor - iCCPMonitor = const_cast< MCCPObserver* >( &aMonitor ); - - // save CCP Supplementary Services observer - iCCPSsObserver = const_cast< MCCPSsObserver* >( &aSsObserver ); - - // get terminal type and wlan mac address, needed for user agent header - iSVPUtility->GetTerminalTypeL( iTerminalType ); - iSVPUtility->GetWlanMACAddressL( iWlanMacAddress ); - - TUid uid = { ccpUid }; - // create Mce Manager, establishes connection to Mce server - iMceManager = CMceManager::NewL( uid, &iContainer ); - - // set observers for asynchronous events - iMceManager->SetSessionObserver( this ); - iMceManager->SetInSessionObserver( this ); - iMceManager->SetInReferObserver( this ); - iMceManager->SetReferObserver( this ); - iMceManager->SetMediaObserver( this ); - iMceManager->SetEventObserver( this ); - iMceManager->SetDtmfObserver( this ); - iMceManager->SetRtpObserver( iRtpObserver ); - - iTrafficStreamCreated = EFalse; - - SVPDEBUG1( "CSVPController::InitializeL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::InitializeL -// --------------------------------------------------------------------------- -// -void CSVPController::InitializeL( const MCCPObserver& aMonitor, - const MCCPSsObserver& aSsObserver ) - { - SVPDEBUG2( "CSVPController::InitializeL iCCPMonitor: 0x%x", iCCPMonitor ) - SVPDEBUG2( "CSVPController::InitializeL iCCPSsObserver: 0x%x", iCCPSsObserver ) - - // See CConvergedCallProvider API documentation. If already called, - // leave with KErrAlreadyExists. - __ASSERT_ALWAYS( !iCCPMonitor, User::Leave( KErrAlreadyExists ) ); - __ASSERT_ALWAYS( !iCCPSsObserver, User::Leave( KErrAlreadyExists ) ); - __ASSERT_ALWAYS( iSVPUtility, User::Leave( KErrNotReady ) ); - __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrNotReady ) ); - - // save CCP monitor - iCCPMonitor = const_cast< MCCPObserver* >( &aMonitor ); - - // save CCP Supplementary Services observer - iCCPSsObserver = const_cast< MCCPSsObserver* >( &aSsObserver ); - - // get terminal type and wlan mac address, needed for user agent header - iSVPUtility->GetTerminalTypeL( iTerminalType ); - iSVPUtility->GetWlanMACAddressL( iWlanMacAddress ); - - // create Mce Manager, establishes connection to Mce server - iMceManager = CMceManager::NewL( KSVPImplementationUid, &iContainer ); - - // set observers for asynchronous events - iMceManager->SetSessionObserver( this ); - iMceManager->SetInSessionObserver( this ); - iMceManager->SetInReferObserver( this ); - iMceManager->SetReferObserver( this ); - iMceManager->SetMediaObserver( this ); - iMceManager->SetEventObserver( this ); - iMceManager->SetDtmfObserver( this ); - iMceManager->SetRtpObserver( iRtpObserver ); - - iTrafficStreamCreated = EFalse; - - SVPDEBUG1( "CSVPController::InitializeL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::NewCallL -// --------------------------------------------------------------------------- -// -MCCPCall* CSVPController::NewCallL( - const CCCPCallParameters& aParameters, - const TDesC& aRecipient, - const MCCPCallObserver& aObserver ) - { - SVPDEBUG1( "CSVPController::NewCallL In" ) - - __ASSERT_ALWAYS( &aParameters, User::Leave( KErrArgument ) ); - __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) ); - __ASSERT_ALWAYS( &aObserver, User::Leave( KErrArgument ) ); - -#ifndef __WINS__ - // Preliminary Call Admission Control implementation, run only if no stream yet open - if ( !iTrafficStreamCreated ) - { - SVPDEBUG1( "CSVPController::NewCallL - Creating WLAN traffic stream.." ) - - TRequestStatus requestStatus; - TUint streamId = 0; - TWlanTrafficStreamParameters streamParams( KSVPWlanTrafficStreamParamUserPriority ); - TWlanTrafficStreamStatus streamStatus = EWlanTrafficStreamStatusActive; - - // Disabling WLAN traffic stream automation and get stream status - iWlanMgmt->CreateTrafficStream( requestStatus, streamParams, streamId, streamStatus ); - User::WaitForRequest( requestStatus ); - - // Save traffic stream ID, needed for stream deletion - iTrafficStreamId = streamId; - - if ( EWlanTrafficStreamStatusInactiveNoBandwidth == streamStatus ) - { - SVPDEBUG1( "CSVPController::NewCallL - No bandwidth in traffic stream, leaving with ECCPErrorNetworkBusy" ) - - // Enabling WLAN traffic stream automation back by deleting used stream - iWlanMgmt->DeleteTrafficStream( requestStatus, iTrafficStreamId ); - User::WaitForRequest( requestStatus ); - - TCCPError err = ECCPErrorNetworkBusy; - User::Leave( err ); - } - SVPDEBUG1( "CSVPController::NewCallL - WLAN traffic stream created, continuing with NewCallL" ) - - iTrafficStreamCreated = ETrue; - } - else - { - SVPDEBUG1( "CSVPController::NewCallL - WLAN traffic stream already created, continuing with NewCallL" ) - ; - } -#endif // __WINS__ - - SVPDEBUG2( "CSVPController::NewCallL aRecipient length = %d", aRecipient.Length() ) - SVPDEBUG2( "CSVPController::NewCallL aRecipient = %S", &aRecipient ) - SVPDEBUG2( "CSVPController::NewCallL Serviceid = %d", aParameters.ServiceId() ) - - // Prepare and remove possible DTMF suffix - HBufC* parsedRecipient = NULL; - parsedRecipient = ParseRecipientDtmfSuffixL( aRecipient ); - - // "convert" recpient to 8-bit format - HBufC8* recipient = HBufC8::NewLC( parsedRecipient->Length() ); // CS:1 - TPtr8 temp = recipient->Des(); - temp.Copy( *parsedRecipient ); - - // Pointer to parsedRecipient no longer needed - delete parsedRecipient; - parsedRecipient = NULL; - - // fetch SIP profile ID from VoIP profiles - RPointerArray< CRCSEProfileEntry > entryArray; - CleanupResetAndDestroy< - RPointerArray >::PushL( entryArray ); //CS:2 - - CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:3 - - // take service id to local variable - TUint32 serviceId = aParameters.ServiceId(); - - // Get VoIP profile by service id - reg->FindByServiceIdL( serviceId, entryArray ); - __ASSERT_ALWAYS( entryArray.Count(), User::Leave( KErrArgument ) ); - - // Take first entry from array - CRCSEProfileEntry* entry = entryArray[0]; - - // create new session - MCCPCall* moSessionTemp = CreateNewSessionL( *recipient, - *entry, - aParameters, - aObserver ); - - CleanupStack::PopAndDestroy( 2, &entryArray ); // CS:1 - CleanupStack::PopAndDestroy( recipient ); // CS:0 - - SVPDEBUG1( "CSVPController::NewCallL Out" ) - return moSessionTemp; - } - -// --------------------------------------------------------------------------- -// CSVPController::CreateNewSessionL -// --------------------------------------------------------------------------- -// -MCCPCall* CSVPController::CreateNewSessionL( - TDesC8& aRecipient, - CRCSEProfileEntry& aVoipProfile, - const CCCPCallParameters& aParameters, - const MCCPCallObserver& aObserver ) - { - SVPDEBUG1( "CSVPController::CreateNewSessionL In" ) - - // array for provisioned data - CDesC8ArrayFlat* userAgentHeaders = new( ELeave ) CDesC8ArrayFlat( 4 ); - CleanupStack::PushL( userAgentHeaders ); // CS:1 - - // variable for storing security status - TUint32 securityStatus( 0 ); - - // set provisioning data - SVPDEBUG1( "CSVPController::CreateNewSessionL Set provisioning data..." ) - iSVPUtility->SetProvisioningDataL( aVoipProfile, - *userAgentHeaders, - securityStatus, - iTerminalType, - iWlanMacAddress ); - - SVPDEBUG2( "CSVPController::CreateNewSessionL Security status: %d", securityStatus ) - SVPDEBUG2( "CSVPController::CreateNewSessionL UAHeaders count: %d", userAgentHeaders->Count() ) - - // Creates a SVP Mo session - CSVPMoSession* moSessionTemp = CSVPMoSession::NewL( *iMceManager, - aRecipient, - aVoipProfile, - aParameters, - iContainer, - *this, - *iSVPUtility, - *iRtpObserver, - securityStatus, - userAgentHeaders ); - CleanupStack::Pop( userAgentHeaders ); // CS:0, to member data - CleanupStack::PushL( moSessionTemp ); // CS:1 - - FinalizeSessionCreationL( moSessionTemp ); - - // set CCP session observer to SVP session - moSessionTemp->AddObserverL( aObserver ); - // set CCP supplementary services events observer to SVP session - moSessionTemp->SetSsObserver( *iCCPSsObserver ); - - CleanupStack::Pop( moSessionTemp ); // CS:0 - - // session pointer is passed to CCP - SVPDEBUG1( "CSVPController::CreateNewSessionL Out" ) - return moSessionTemp; - } - -// --------------------------------------------------------------------------- -// Releases call -// --------------------------------------------------------------------------- -// -TInt CSVPController::ReleaseCall( MCCPCall& aCall ) - { - SVPDEBUG1( "CSVPController::ReleaseCall In" ) - - TInt response = KErrNotFound; - - // To ensure correct value - iIncomingReferCallIndex = KErrNotFound; - iSessionUpdateOngoing = EFalse; - - for ( TInt i = 0; i < iSessionArray.Count(); i++ ) - { - if ( iSessionArray[i] == &aCall ) - { - if ( iDtmfStringSending ) - { - SVPDEBUG1( "CSVPController::ReleaseCall - Abort DTMF Sending" ) - - // send abort event - iSessionArray[i]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceAbort, - KErrNone, - iDtmfStringLex.Peek() ); - - SVPDEBUG1( "CSVPController::ReleaseCall - Complete DTMF" ) - - // send sequence completed event - iSessionArray[i]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, - KErrNone, - iDtmfStringLex.Peek() ); - - // sequence complete, clear flags - iDtmfStringSending = EFalse; - iFirstDtmfSent = EFalse; - - delete iDtmfString; - iDtmfString = NULL; - } - iSessionArray[i]->Release(); - response = KErrNone; - } - } - -#ifndef __WINS__ - // Preliminary Call Admission Control implementation, delete only if created in NewCallL - if ( iTrafficStreamCreated ) - { - SVPDEBUG1( "CSVPController::ReleaseCall - Deleting WLAN traffic stream" ) - - TRequestStatus requestStatus; - - // Enabling WLAN traffic stream automation back by deleting used stream - iWlanMgmt->DeleteTrafficStream( requestStatus, iTrafficStreamId ); - User::WaitForRequest( requestStatus ); - - iTrafficStreamCreated = EFalse; - - SVPDEBUG1( "CSVPController::ReleaseCall - WLAN traffic stream deleted" ) - } - else - { - SVPDEBUG1( "CSVPController::ReleaseCall - No WLAN traffic stream to delete" ) - ; - } -#endif // __WINS__ - - SVPDEBUG1( "CSVPController::ReleaseCall Out" ) - return response; - } - -// --------------------------------------------------------------------------- -// Releases emergency call -// --------------------------------------------------------------------------- -// -TInt CSVPController::ReleaseEmergencyCall( MCCPEmergencyCall& /*aCall*/ ) - { - SVPDEBUG1( "CSVPController::ReleaseEmergencyCall In" ) - - // To ensure correct value next time - iIncomingReferCallIndex = KErrNotFound; - iSessionUpdateOngoing = EFalse; - - delete iEmergencySession; - iEmergencySession = NULL; - - SVPDEBUG1( "CSVPController::ReleaseEmergencyCall Out" ) - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Releases conference call -// --------------------------------------------------------------------------- -// -TInt CSVPController::ReleaseConferenceCall( MCCPConferenceCall& /*aCall*/ ) - { - SVPDEBUG1( "CSVPController::ReleaseConferenceCall In" ) - SVPDEBUG1( "CSVPController::ReleaseConferenceCall Out" ) - return KErrNotSupported; - } - -// --------------------------------------------------------------------------- -// CSVPController::RemoveFromArray -// --------------------------------------------------------------------------- -// -void CSVPController::RemoveFromArray( CSVPSessionBase& aSession ) - { - SVPDEBUG1( "CSVPController::RemoveFromArray In" ) - - // When Sessions destructor is called object be removed from array - // manually after when data has been deleted. - SVPDEBUG2( "CSVPController::RemoveFromArray aSession: 0x%x", &aSession ) - - TInt index = FindSVPSession( aSession.Session() ); - if ( KErrNotFound != index ) - { - SVPDEBUG1( "CSVPController::RemoveFromArray Session found - removing" ) - iSessionArray.Remove( index ); - iSessionArray.Compress(); - } - - // Try also to remove it from RTCP observer. Ingore the return code, yet - // again this is "just in case" thing. - iRtpObserver->RemoveSessionFromObserving( &aSession ); - SVPDEBUG1( "CSVPController::RemoveFromArray Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::FindSVPSession -// --------------------------------------------------------------------------- -// -TInt CSVPController::FindSVPSession( const CMceSession& aSession ) const - { - SVPDEBUG1( "CSVPController::FindSVPSession In" ) - - TInt count = iSessionArray.Count(); - SVPDEBUG2( "CSVPController::FindSVPSession count = %d", count ) - - while ( count ) - { - count--; - - if ( &iSessionArray[count]->Session() == &aSession ) - { - SVPDEBUG2( "CSVPController::FindSVPSession Out return: %d", count ) - return count; - } - } - - SVPDEBUG1( "CSVPController::FindSVPSession Out return: KErrNotFound" ) - return KErrNotFound; - } - -// --------------------------------------------------------------------------- -// CSVPController::Uid -// --------------------------------------------------------------------------- -// -const TUid& CSVPController::Uid() const - { - SVPDEBUG1( "CSVPController::Uid" ) - return KSVPImplementationUid; - } - -// --------------------------------------------------------------------------- -// CSVPController::CreateNonSecureSessionL -// --------------------------------------------------------------------------- -// -void CSVPController::CreateNonSecureSessionL( TInt aSessionIndex ) - { - SVPDEBUG1( "CSVPController::CreateNonSecureSessionL In" ) - - // secure session failed -> create non secure Mo session - static_cast< CSVPMoSession* >( iSessionArray[ aSessionIndex ] )-> - CreateNonSecureSessionL( *iMceManager ); - - SVPDEBUG1( "CSVPController::CreateNonSecureSessionL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckIfSecureFailed -// --------------------------------------------------------------------------- -// -TBool CSVPController::CheckIfSecureFailed( TInt aStatusCode ) const - { - SVPDEBUG2( "CSVPController::CheckIfSecureFailed In, aStatusCode: %d", aStatusCode ) - - // if secure fails with the following response codes - // normal session is tried next - if ( KSVPNotAcceptableHereVal == aStatusCode || - KSVPNotAcceptableVal == aStatusCode || - KSVPPreconditionFailureVal == aStatusCode || - KSVPMethodNotAllowedVal == aStatusCode ) - { - SVPDEBUG1( "CSVPController::CheckIfSecureFailed Out ETrue" ) - return ETrue; - } - else - { - SVPDEBUG1( "CSVPController::CheckIfSecureFailed Out EFalse" ) - return EFalse; - } - } - -// --------------------------------------------------------------------------- -// CSVPController::SessionStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::SessionStateChanged( CMceSession& aSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged In" ) - - // Note, getting the status code may reset it in the container. So do it - // only once and be sure that it stays as it should be. - const TInt statusCode = aContainer->GetStatusCode(); - SVPDEBUG2( "CSVPController::SessionStateChanged statusCode: %d", statusCode ) - - // check if this is emergency session - if ( iEmergencySession ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged, emergency session" ) - - if ( CMceSession::EEstablished == aSession.State() ) - { - // Rest of the profiles not needed since session is established - iEmergencyProfileIds.Reset(); - iEmergencyIapIds.Reset(); - } - - if ( CMceSession::EEstablished == aSession.State() && - iEmergencySession->HasHoldController() && - ( ( iEmergencySession->HoldController() ).HoldInProgress() || - ( iEmergencySession->HoldController() ).HoldRolledBack() ) ) - { - // Handle hold - TRAPD( error, iEmergencySession->HoldSessionStateChangedL( aSession ) ) - - if ( error ) - { - SVPDEBUG2( "CSVPController::SessionStateChanged, emergency session error %d", error ) - } - } - else - { - iEmergencySession->SessionStateChanged( statusCode ); - } - } - else if ( iSessionUpdateOngoing ) - { - // Non-hold session update, e.g. codec renegotiation ongoing; no actions - // needed until MCE session state is established. - SVPDEBUG1( "CSVPController::SessionStateChanged - MT Session Update" ) - - if ( CMceSession::EEstablished == aSession.State() ) - { - // Session update done (Ack received) - iSessionUpdateOngoing = EFalse; - SVPDEBUG1( "CSVPController::SessionStateChanged - MT Session Updated" ) - } - } - else - { - // fetch correct session - const TInt ind = FindSVPSession( aSession ); - - // KErrNone = status, status had to be error code - if ( KErrNotFound != ind && - iSessionArray[ ind ]->SecurePreferred() && - CheckIfSecureFailed( statusCode ) || - CMceSession::ECancelling == aSession.State() ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged - Secure failed, trying normal session" ) - - // trying normal session after secure session trial failed - TRAPD( err, CreateNonSecureSessionL( ind ) ); - - if ( err ) - { - iSessionArray[ ind ]->GetCCPSessionObserver(). - ErrorOccurred( ECCPRedirection, iSessionArray[ ind ] ); - iSessionArray[ ind ]->GetCCPSessionObserver(). - CallStateChanged( MCCPCallObserver::ECCPStateIdle, - iSessionArray[ ind ]); - } - } - else if ( KErrNotFound != ind ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged - Session found" ) - - CSVPSessionBase* session = iSessionArray[ ind ]; - - if ( !session->CallId() && - KSVPMultipleChoicesVal != statusCode && - KSVPMovedPermanentlyVal != statusCode && - KSVPMovedTemporarilyVal != statusCode ) - { - // CallId not stored yet and not a 3XX case, - // check and store headers data. - CheckHeadersData( session, aContainer ); - } - - if ( !session->SecurePreferred() ) - { - session->ReleaseTempSecure(); - } - - // Release attended transfer target session index - // if e.g. early stage session terminate - if ( CMceSession::ETerminated == aSession.State() ) - { - iHoldCallIndex = KErrNotFound; - } - - if ( CMceSession::EProceeding == aSession.State() ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged EProceeding" ) - - if ( KErrNotFound != iHoldCallIndex && iSessionArray.Count() > 1 ) - { - SVPDEBUG3( "CSVPController::SessionStateChanged, atte trans target, ind %d, iHCInd %d", - ind, iHoldCallIndex ) - CheckCallEventToBeSent( session, iSessionArray[iHoldCallIndex] ); - ExecCbIncomingCall( session, *iSessionArray[iHoldCallIndex] ); - iHoldCallIndex = KErrNotFound; - } - else if ( session->HasHoldController() && - ( session->HoldController() ).HoldInProgress() ) - { - // Do nothing here; this only prevents wrong new call - // callback to CCP. - SVPDEBUG1( "CSVPController::SessionStateChanged - HoldInProgress" ) - } - else if ( session->IsEmptyReInvite() ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged - Empty re-Invite handling ongoing" ) - } - else if ( !session->IsIdle() ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged - NOP" ) - } - else - { - SVPDEBUG1( "CSVPController::SessionStateChanged Incoming" ) - ExecCbIncomingCall( session ); - session->SessionStateChanged( statusCode ); - } - } - else if ( CMceSession::EEstablished == aSession.State() && - session->HasHoldController() && - ( ( session->HoldController() ).HoldInProgress() || - ( session->HoldController() ).HoldRolledBack() ) ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged EEstablished & HoldController" ) - - session->HandleSessionStateChanged( aSession ); - } - else if ( ( CMceSession::EEstablished == aSession.State() || - CMceSession::ETerminated == aSession.State() ) && - KErrNone != statusCode && - KErrNotFound != iIncomingReferCallIndex && - iIncomingReferCallIndex < iSessionArray.Count() && - iSessionArray[ iIncomingReferCallIndex ]->IsIncomingTransfer() ) - { - SVPDEBUG1( "CSVPController::SessionStateChanged transferor" ) - - // Transferor sends notify to original when new session connected/failed. - // If secure is mandatory but path unsecure, attended transfer req must be rejected - if ( session->SecureMandatory() && - CMceSession::EControlPathUnsecure == aSession.ControlPathSecurityLevel() && - iSessionArray[ iIncomingReferCallIndex ]->IsAttended() ) - { - iSessionArray[ iIncomingReferCallIndex ]->SendNotify( KSVPDeclineVal ); - } - else - { - iSessionArray[ iIncomingReferCallIndex ]->SendNotify( statusCode ); - } - - if ( iSessionArray[ iIncomingReferCallIndex ]->IsAttended() ) - { - // remotepartyinfo and/or secure status might have been changed, - // proper event will be sent later on. - CheckCallEventToBeSent( session, iSessionArray[iIncomingReferCallIndex] ); - } - iIncomingReferCallIndex = KErrNotFound; - session->SessionStateChanged( statusCode ); - } - // 3xx Call forward handling - else if ( KSVPMultipleChoicesVal == statusCode || - KSVPMovedPermanentlyVal == statusCode || - KSVPMovedTemporarilyVal == statusCode ) - { - HandleCallForward( statusCode, ind, aContainer ); - } - else - { - if ( ( aSession.State() == CMceSession::EOffering || - aSession.State() == CMceSession::ETerminating || - aSession.State() == CMceSession::ETerminated ) && - iSessionArray[ ind ]->HasHoldController() && - ( ( iSessionArray[ ind ]->HoldController() ).HoldInProgress() || - ( iSessionArray[ ind ]->HoldController() ).HoldRolledBack() ) ) - { - // Failed hold e.g. 408 response - SVPDEBUG1("CSVPController::SessionStateChanged()\ - State change: Failed && HoldController"); - if ( 491 == statusCode ) - { - SVPDEBUG1( - "CSVPController::SessionStateChanged - UpdateFailed()" ) - UpdateFailed( aSession, aContainer ); - } - else if ( 100 <= statusCode && 200 > statusCode ) // Provisional response - { - // NOP - SVPDEBUG1( - "CSVPController::SessionStateChanged - Provisional - NOP" ) - } - else - { - iSessionArray[ ind ]->HandleSessionStateChanged( aSession ); - session->SessionStateChanged( statusCode ); - } - } - - else if ( session->HasHoldController() ) - { - // MCE Session Refresh; no actions by the SVP - SVPDEBUG1( - "CSVPController::SessionStateChanged - Session refresh" ) - if ( CMceSession::ETerminating == aSession.State() || - CMceSession::ETerminated == aSession.State() ) - { - session->SessionStateChanged( statusCode ); - } - } - else if ( !iFailed ) - { - SVPDEBUG1( - "CSVPController::SessionStateChanged - Not handled -> Notify session" ) - session->SessionStateChanged( statusCode ); - } - else - { - // Failed() callback occurred before EEstablished state - // -> No action needed, session termination timer is set - } - } - } - else - { - SVPDEBUG1( "CSVPController::SessionStateChanged else" ) - } - } - - SVPDEBUG1( "CSVPController::SessionStateChanged Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::SessionConnectionStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::SessionConnectionStateChanged( - CMceSession& aSession, - TBool aActive ) - { - SVPDEBUG2("CSVPController::SessionConnectionStateChanged Active ETrue, Inactive EFalse: %d", aActive ) - - if ( iEmergencySession ) - { - iEmergencySession->SessionConnectionStateChanged( aSession, aActive ); - } - } - -// --------------------------------------------------------------------------- -// CSVPController::Failed -// --------------------------------------------------------------------------- -// -#ifdef _DEBUG -void CSVPController::Failed( CMceSession& aSession, TInt aError ) -#else -void CSVPController::Failed( CMceSession& aSession, TInt /*aError*/ ) -#endif // _DEBUG - { - SVPDEBUG1("CSVPController::Failed In" ) - SVPDEBUG2("CSVPController::Failed With error code: %d", aError ) - - TInt ind = FindSVPSession( aSession ); - - if ( KErrNotFound != ind ) - { - SVPDEBUG1("CSVPController::Failed() Session found") - - if ( &iSessionArray[ ind ]->GetCCPSessionObserver() ) - { - iSessionArray[ ind ]->GetCCPSessionObserver(). - ErrorOccurred( ECCPErrorConnectionError, - iSessionArray[ ind ] ); - - // Actually MCE session state should always - // be ETerminated when this method is - // called; but check anyway: - if ( CMceSession::ETerminated == aSession.State() ) - { - iFailed = ETrue; - // start termination timer, needed for UI - // to handle Disconnected-bubble - TRAP_IGNORE( iSessionArray[ ind ]->StartTimerL( - KSVPTerminatingTime, KSVPTerminationTimerExpired ) ); - - iSessionArray[ ind ]->GetCCPSessionObserver(). - CallStateChanged( MCCPCallObserver::ECCPStateDisconnecting, - iSessionArray[ ind ] ); - - SVPDEBUG1("CSVPController::Failed() Session terminating"); - } - } - else - { - iCCPMonitor->ErrorOccurred( MCCPObserver::ECCPIncomingCallFailed ); - } - } - else - { - SVPDEBUG1("CSVPController::Failed() Session not Found!!"); - } - - SVPDEBUG1("CSVPController::Failed Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::UpdateFailed -// --------------------------------------------------------------------------- -// -void CSVPController::UpdateFailed( - CMceSession& aSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::UpdateFailed In" ) - - TInt ind = FindSVPSession( aSession ); - TInt statusCode = aContainer->GetStatusCode(); - - SVPDEBUG2( "CSVPController::UpdateFailed statusCode: %d", statusCode ) - - if ( KErrNotFound != ind ) - { - iSessionArray[ ind ]->UpdateFailed( aSession, statusCode ); - } - iSessionUpdateOngoing = EFalse; - SVPDEBUG1( "CSVPController::UpdateFailed Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::EventStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::EventStateChanged( - CMceEvent& aEvent, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController:EventStateChanged In" ) - - iContainer = *aContainer; - TInt ind = FindSVPSession( *aEvent.AssociatedSession() ); - TInt statusCode = iContainer.GetStatusCode(); - - SVPDEBUG2( "CSVPController:EventStateChanged statusCode: %d", statusCode ) - - if ( KErrNotFound != ind ) - { - SVPDEBUG2( "CSVPController::EventStateChanged ind = %d", ind ) - TInt err = iSessionArray[ ind ]->EventStateChanged( aEvent, statusCode ); - - if ( KSVPOKVal == statusCode && - iSessionArray[ ind ]->IsAttended() && - KErrNone == err ) - { - SVPDEBUG1( "CSVPController::EventStateChanged Atte transfer cont." ) - - TRAP( err, CreateNewTransferSessionL( ind, ETrue ) ); - - if ( err ) - { - SVPDEBUG2( "CSVPController::EventStateChanged: err: %d", err ) - } - } - } - else - { - SVPDEBUG1( "CSVPController::EventStateChanged Session not Found!!" ) - } - - SVPDEBUG1("CSVPController:EventStateChanged OUT"); - } - -// --------------------------------------------------------------------------- -// CSVPController::NotifyReceived -// --------------------------------------------------------------------------- -// -void CSVPController::NotifyReceived( - CMceEvent& aEvent, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::NotifyReceived In" ) - - TInt ind = FindSVPSession( *aEvent.AssociatedSession() ); - - if ( KErrNotFound != ind ) - { - iSessionArray[ ind ]->NotifyReceived( aEvent, aContainer ); - } - else - { - SVPDEBUG1( "CSVPController::NotifyReceived, session not found !" ) - } - - SVPDEBUG1( "CSVPController::NotifyReceived Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::EventConnectionStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController:: EventConnectionStateChanged( - CMceEvent& /*aEvent*/, - TBool /*aActive*/ ) - { - SVPDEBUG1( "CSVPController:: EventConnectionStateChanged In" ) - SVPDEBUG1( "CSVPController:: EventConnectionStateChanged Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::Failed -// --------------------------------------------------------------------------- -// -#ifdef _DEBUG -void CSVPController::Failed( CMceEvent& /*aEvent*/, TInt aError ) -#else -void CSVPController::Failed( CMceEvent& /*aEvent*/, TInt /*aError*/ ) -#endif // _DEBUG - { - SVPDEBUG2("CSVPController::Failed Event failure, error: %d", aError ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingSession -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingSession( - CMceInSession* aSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::IncomingSession In" ) - SVPDEBUG2( "CSVPController::IncomingSession - status code: %d", aContainer->GetStatusCode() ) - - if ( iEmergencySession ) - { - SVPDEBUG1( "CSVPController::IncomingSession - ongoing emergency call - reject incoming call" ) - TRAP_IGNORE( aSession->RejectL( KSVPBusyHereReason, KSVPBusyHereVal ) ) - // Ownership of aSession is changed, delete it - delete aSession; - aSession = NULL; - return; - } - - // IncomingSessionHandlerL is used to handle possible leave - SVPDEBUG1( "CSVPController::IncomingSession IncomingSessionHandlerL" ) - TRAPD( err, IncomingSessionHandlerL( aSession, aContainer ) ); - - if ( err ) - { - SVPDEBUG2( "CSVPController::IncomingSession: err: %d", err ) - - // RejectL must be called in case SVP needs to delete session. - // TRAP is used because of RejectL might contain a leaver. - switch ( err ) - { - case KErrNotSupported: - { - TRAP( err, aSession->RejectL( KSVPCallTransactDoesNotExistReason, - KSVPCallDoesNotExistVal ) ); - break; - } - - case KSVPErrWrongMinSE: - // NOP. Reject has been done as a result of call to - // IncomingSessionHandlerL. - break; - - case KSVPErrDnDRejection: - { - // Reject call because of Do not Disturb service active. - TRAP( err, aSession->RejectL( KSVPBusyHereReason, - KSVPBusyHereVal ) ); - break; - } - - case KSVPErrAnonymousCallRejection: - { - // Reject call because of Anonymous Barring service active. - TRAP( err, aSession->RejectL( KSVPNotAcceptableHereReason, - KSVPNotAcceptableHereVal ) ); - break; - } - - case KSVPErrCodecMismatch: - { - TRAP( err, aSession->RejectL( KSVPIncompatibleMediaFormatReason, - KSVPNotAcceptableHereVal ) ); - break; - } - - default: - { - // NOP. - break; - } - } - - if ( KErrNotFound == FindSVPSession( *aSession ) ) - { - // Leave has occured before CSVPMtSession was created. - delete aSession; - } - else - { - SVPDEBUG1( "CSVPController::IncomingSession IncomingSessionHandlerL leave occurred" ) - // clean up session - TerminateSession( *aSession ); - } - } - } - -// --------------------------------------------------------------------------- -// CSVPController::TerminateSession -// --------------------------------------------------------------------------- -// -void CSVPController::TerminateSession( CMceInSession& aSession ) - { - SVPDEBUG1( "CSVPController::TerminateSession In" ) - - // find correct session - TInt index = FindSVPSession( aSession ); - - if ( KErrNotFound != index ) - { - CSVPSessionBase* tempBase = iSessionArray[ index ]; - // remove session pointer from array and compress array - iSessionArray.Remove( index ); - iSessionArray.Compress(); - - // delete session - delete tempBase; - tempBase = NULL; - } - - SVPDEBUG1( "CSVPController::TerminateSession Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckMinSessionExpiresL -// --------------------------------------------------------------------------- -// -void CSVPController::CheckMinSessionExpiresL( CMceInSession& aSession, - CDesC8Array& aHeaders, - TInt aMinSE ) - { - SVPDEBUG1( "CSVPController::CheckMinSessionExpiresL In" ) - - TInt count = aHeaders.MdcaCount(); - TUint32 sessionExpires = 0; - TInt error = KErrNone; - while ( count-- ) - { - TPtrC8 tmpHeader = aHeaders.MdcaPoint( count ); - if ( KErrNotFound != tmpHeader.Find( KSVPSessionExpires ) ) - { - // "Session-Expires:" found - SVPDEBUG1( "CSVPController::CheckMinSEL: 'Session-Expires:' found" ) - - TInt offset = tmpHeader.FindF( KSVPRefresher ); - if ( KErrNotFound != offset ) - { - tmpHeader.Set( tmpHeader.Left( offset ) ); - } - - TPtrC8 header; - header.Set( tmpHeader ); - if ( header.FindF( KSVPCln ) ) - { - // 5 digits should be enought for Min-SE - // For example: "Min-SE: 1200" - TLex8 expires( header.Right( 5 ) ); - TInt digits = 0; - while ( !expires.Eos() ) - { - if ( expires.Peek().IsDigit() ) - { - digits++; - } - expires.Inc(); - } - TLex8 expiresVal( header.Right( digits ) ); - error = expiresVal.Val( sessionExpires, EDecimal ); - SVPDEBUG2(" CSVPController::CheckMinSEL sesExp: %d", sessionExpires ) - - if ( error || aMinSE > sessionExpires ) - { - SVPDEBUG2(" CSVPController::CheckMinSEL reject, err: %d", error ) - CDesC8ArrayFlat* minSEHeader = - new ( ELeave ) CDesC8ArrayFlat( 1 ); - CleanupStack::PushL( minSEHeader ); // CS:0 - - HBufC8* header = HBufC8::NewL( - KSVPMinExpiresLenght + digits ); - CleanupStack::PushL( header ); // CS:1 - - header->Des().Copy( KSVPMinSessionExpires ); - header->Des().AppendNum( aMinSE ); - minSEHeader[ 0 ].AppendL( *header ); - CleanupStack::PopAndDestroy( header ); // CS:1 - - aSession.RejectL( KSVPIntervalTooSmallReason, - KSVPSessionIntervalTooSmallVal, - minSEHeader ); - - // ownership to Mce - CleanupStack::Pop( minSEHeader ); // CS:0 - User::Leave( KSVPErrWrongMinSE ); - } - } - } - } - - SVPDEBUG1( "CSVPController::CheckMinSessionExpiresL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::FetchExpiresTime -// --------------------------------------------------------------------------- -// -void CSVPController::FetchExpiresTime( TUint32& aExpiresTime, - CDesC8Array& aHeaders ) const - { - SVPDEBUG1( "CSVPController::FetchExpiresTime In" ) - - TBool expiresTaken = EFalse; - for ( TInt i = 0; i < aHeaders.MdcaCount() && !expiresTaken; i++ ) - { - TPtrC8 tmpHeader = aHeaders.MdcaPoint( i ); - if ( KErrNotFound != tmpHeader.Find( KSVPExpiresHeader ) && - KErrNotFound == tmpHeader.Find( KSVPSessionExpires ) ) - { - // "Expires:" found - SVPDEBUG1(" CSVPController::FetchExpiresTimer: 'Expires:' found") - - TInt colonMark = tmpHeader.FindF( KSVPCln ); - - if ( colonMark ) - { - - TLex8 expires( tmpHeader.Right( 5 ) ); // three digits max - TInt digits = 0; - while ( !expires.Eos() ) - { - if ( expires.Peek().IsDigit() ) - { - digits++; - } - expires.Inc(); - } - TLex8 expiresVal( tmpHeader.Right( digits ) ); - TInt error = expiresVal.Val( aExpiresTime, EDecimal ); - - if ( error ) - { - SVPDEBUG2(" CSVPController::FetchExpiresTimer, set default value\ - Val error: %d", error ); - // if error occurred, set default time - aExpiresTime = KSVPDefaultExpiresTime; - expiresTaken = ETrue; - } - else if ( KSVPDefaultExpiresTime < aExpiresTime ) - { - aExpiresTime = KSVPDefaultExpiresTime; - expiresTaken = ETrue; - } - else - { - SVPDEBUG2(" CSVPController::FetchExpiresTime: %d", aExpiresTime ) - expiresTaken = ETrue; - } - } - } - } - - SVPDEBUG1( "CSVPController::FetchExpiresTime Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingSessionHandlerL -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingSessionHandlerL( CMceInSession* aSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL In" ) - - __ASSERT_ALWAYS( aSession, User::Leave( KErrArgument ) ); - __ASSERT_ALWAYS( aContainer, User::Leave( KErrArgument ) ); - - CDesC8Array* headers = aContainer->GetHeaders(); - __ASSERT_ALWAYS( headers, User::Leave( KErrArgument ) ); - CleanupStack::PushL( headers ); // CS:1 - - IsTransferTargetCaseL( headers ); - - // check if Require header contains precondition and that Supported header - // includes option tag 100rel, providing support for PRACK's - iPreconditions = IsPreconditionRequired( *headers ); - - // Default expiration time (120 s) is set due IOP issue, - // otherwise incoming call would continue eternity in some cases. - TUint32 expireTime = KSVPDefaultExpiresTime; - // check if expires header is present and update expiration time - FetchExpiresTime( expireTime, *headers ); - - // mt session temp - CSVPMtSession* mtSessionTemp = NULL; - - CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:2 - - RPointerArray< CRCSEProfileEntry > voipProfiles; - CleanupResetAndDestroy< RPointerArray< CRCSEProfileEntry > >::PushL( - voipProfiles ); // CS:3 - - reg->FindBySIPProfileIdL( aSession->Profile(), voipProfiles ); - - // Take first profile from the array - const TUint32 voipProfileId = voipProfiles[ 0 ]->iId; - const TUint32 minSE = voipProfiles[ 0 ]->iSIPMinSE; - - CheckMinSessionExpiresL( *aSession, *headers, minSE ); - - SVPDEBUG2("CSVPController::IncomingSessionHandlerL VoIP profile id: %d", - voipProfileId ); - - // Take first profile from the array - const TUint32 serviceId = voipProfiles[ 0 ]->iServiceProviderId; - - SVPDEBUG2("CSVPController::IncomingSessionHandlerL Service id: %d", - serviceId ); - - // create SIP and ProfileRegistry for profile handling - CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS: 4 - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL sip CREATED" ); - - CSIPProfileRegistry* sipProfileRegistry = - CSIPProfileRegistry::NewLC( *sip, *this ); // CS: 5 - - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL\ - profile registry CREATED" ); - - // retrieve SIP profile by using sip profile id, note ownership transfer - CSIPProfile* profile = sipProfileRegistry->ProfileL( aSession->Profile() ); - - // Get keep-alive timer value - TUint32 iapId = 0; - TBool found = EFalse; - TInt keepAliveValue; - - profile->GetParameter( KSIPAccessPointId, iapId ); - - TRAPD( errKeepAlive, - found = iSVPUtility->GetKeepAliveByIapIdL( iapId, keepAliveValue ) ); - - SVPDEBUG3( "CSVPController::IncomingSessionHandlerL\ - GetKeepAliveByIapIdL: errKeepAlive = %d found = %d", - errKeepAlive, found ); - - if ( !found ) - { - const TDesC8* aor; - profile->GetParameter( KSIPUserAor, aor ); - TRAP( errKeepAlive, found = - iSVPUtility->GetKeepAliveByAORL( *aor, keepAliveValue ) ); - - SVPDEBUG3( "CSVPController::IncomingSessionHandlerL\ - GetKeepAliveByAORL: errKeepAlive = %d found = %d", - errKeepAlive, found ); - } - - delete profile; - CleanupStack::PopAndDestroy( 2, sip ); // CS:3 - - CMceRtpSource* rtpSource = NULL; - - // modify codecs and codec settings if streams found - if ( aSession->Streams().Count() ) - { - const RPointerArray& streams = aSession->Streams(); - - SVPDEBUG2("CSVPController::IncomingSessionHandlerL Streamcount: %d", - streams.Count() ); - - // disable rtp source and speaker sink so that audio is not on - // before session is up signalling-wise - for ( TInt i = 0; i < streams.Count(); i++ ) - { - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL disabling" ); - - CMceMediaStream* stream1 = streams[i]; - - // if stream is not audio stream -> remove - if ( KMceAudio != stream1->Type() ) - { - aSession->RemoveStreamL( *streams[ i ] ); - } - else - { - // search for RTP source - if ( stream1->Source() && - KMceRTPSource == stream1->Source()->Type() ) - { - SVPDEBUG1( - "CSVPController::IncomingSessionHandlerL\ - RTPSource found" ); - - rtpSource = static_cast( - stream1->Source() ); - } - - SVPAudioUtility::DisableSpeakerSinkL( stream1->Sinks() ); - SVPAudioUtility::DisableMicSourceL( *stream1 ); - } - } - - // sets MMF priorities and sets codec specific settings - CheckStreamsL( *voipProfiles[ 0 ], *aSession, keepAliveValue ); - if ( rtpSource ) - { - iSVPUtility->UpdateJitterBufferSizeL( *rtpSource ); - } - - // create SVP Mt session - mtSessionTemp = CSVPMtSession::NewL( aSession, - iContainer, - serviceId, - voipProfileId, - *this, - *iSVPUtility, - *iRtpObserver, - keepAliveValue, - iPreconditions ); - - CleanupStack::PushL( mtSessionTemp ); - FinalizeSessionCreationL( mtSessionTemp ); - CleanupStack::Pop( mtSessionTemp ); - } - else - { - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL NO streams!" ); - - // no streams found, handle streams like in Mo-case - mtSessionTemp = CSVPMtSession::NewL( aSession, - iContainer, - serviceId, - voipProfileId, - *this, - *iSVPUtility, - *iRtpObserver, - keepAliveValue, - iPreconditions ); - - CleanupStack::PushL( mtSessionTemp ); - // construct audio streams - mtSessionTemp->ConstructAudioStreamsL(); - FinalizeSessionCreationL( mtSessionTemp ); - CleanupStack::Pop( mtSessionTemp ); - } - - CleanupStack::PopAndDestroy( 3, headers ); // CS:0 - - // set expires timer - if ( expireTime ) - { - SVPDEBUG2( "CSVPController::IncomingSessionHandlerL expireTime: %i s.", expireTime ); - mtSessionTemp->StartTimerL( KSVPMilliSecondCoefficient * expireTime, - KSVPExpiresTimeExpired ); - } - - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL Updating call" ); - - aSession->UpdateL(); - - SVPDEBUG2( "CSVPController::IncomingSessionHandlerL, Call state after update: %i", - aSession->State() ); - - if ( CMceSession::EProceeding == aSession->State() ) - { - const TInt ind = FindSVPSession( *aSession ); - iCCPMonitor->IncomingCall( iSessionArray[ ind ] ); - - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL - EProceeding" ); - - iSessionArray[ ind ]->SessionStateChanged( KErrNone ); - } - - // reset flag - iPreconditions = EFalse; - - SVPDEBUG1( "CSVPController::IncomingSessionHandlerL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckStreamsL -// --------------------------------------------------------------------------- -// -void CSVPController::CheckStreamsL( CRCSEProfileEntry& aVoipProfile, - CMceSession& aInSession, - TInt aKeepAliveValue, - TBool aSessionUpdateOngoing) - { - SVPDEBUG1( "CSVPController::CheckStreamsL In" ) - - __ASSERT_ALWAYS( &aInSession, User::Leave( KErrArgument ) ); - - const RPointerArray< CMceMediaStream >& streamArray = - aInSession.Streams(); - - const TInt streamCount( streamArray.Count() ); - - SVPDEBUG3("CSVPController::CheckStreamsL aVoIPProfileId: %u streamCount: %d ", - aVoipProfile.iId, streamCount ); - - // Set codec settings, this also removes unneeded codecs. - for ( TInt i = 0; i < streamCount; i++ ) - { - iSVPUtility->SetAudioCodecsMTL( aVoipProfile, - *streamArray[ i ], - aKeepAliveValue, - aSessionUpdateOngoing ); - - // Set the priorities for the remaining codecs. This will handle also the - // DTMF priorites once correct codecs are set in the streams. Also note - // the downlink/uplink (in/out) discrimination. - - if ( KMceAudio == streamArray[i]->Type() && - streamArray[i]->BoundStream() ) - { - SVPDEBUG2( "CSVPController::CheckStreamsL round: %d start", i ) - - CMceAudioStream* stream = static_cast( streamArray[i] ); - - TBool dtmfMode = EFalse; - if ( SVPAudioUtility::IsDownlinkStream( *stream ) ) - { - dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL( *stream, - static_cast( stream->BoundStreamL() ) ); - } - else - { - dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL( - static_cast( stream->BoundStreamL() ), - *stream ); - } - - iSVPUtility->SetDtmfMode( dtmfMode ); - - SVPDEBUG2( "CSVPController::CheckStreamsL round: %d done", i ) - } - } - - SVPDEBUG1( "CSVPController::CheckStreamsL Out" ) - } - -// ----------------------------------------------------------------------------- -// CSVPController::GetCallIdFromUserHeadersL -// Extract call id from user headers -// ----------------------------------------------------------------------------- -// -TBool CSVPController::GetCallIdFromUserHeadersL( - const CDesC8Array& aUserHeaders, - TDes8& aCallId ) - { - // All variables is used for parser. - TInt tmpMark1 = 0; - TInt tmpMark2 = 0; - - TBool found = EFalse; - - // Find replaces header descriptor from userheaders array. - for ( TInt m = 0; &aUserHeaders && m < aUserHeaders.Count() && !found; m++ ) - { - TPtrC8 tmpHeader = aUserHeaders[m]; - if ( KErrNotFound != tmpHeader.FindF( KSVPReplacesColonTxt ) ) - { - SVPDEBUG1(" CSVPController::\ - GetCallIdFromUserHeadersL: Replaces: found:"); - - // variables used for parse tags from replaces header. - tmpMark1 = tmpHeader.Locate( KSVPColonMark ); - tmpMark2 = tmpHeader.Locate( KSVPSemiColonMark ); - if ( KErrNotFound == tmpMark1 || - KErrNotFound == tmpMark2 ) - { - SVPDEBUG3("CSVPController::GetCallIdFromUserHeadersL leave \ - tmpMark1: %d, tmpMark2: %d", tmpMark1, tmpMark2 ) - User::Leave( KErrArgument ); - } - - // Call id is between tmpMark1 and tmpMark2 and there is a space - // between Replaces: -text and callid - if ( ( tmpHeader.Mid( tmpMark1+2, tmpMark2 - tmpMark1 - 2 ).Length() < KSVPTempStringlength ) ) - { - aCallId.Copy( - tmpHeader.Mid( tmpMark1+2, tmpMark2 - tmpMark1 - 2 ) ); - - found = ETrue; - } - else - { - SVPDEBUG1(" CSVPController::\ - GetCallIdFromUserHeadersL: Replaces: Too long, Leave"); - User::Leave( KErrArgument ); - } - } - } - - SVPDEBUG2( "CSVPController::GetCallIdFromUserHeadersL return %d", found ) - return found; - } - -// ----------------------------------------------------------------------------- -// CSVPController::IsTransferTargetCaseL -// ----------------------------------------------------------------------------- -// -void CSVPController::IsTransferTargetCaseL( CDesC8Array* aHeaders ) - { - SVPDEBUG1( "CSVPController::IsTransferTargetCaseL In" ) - - iHoldCallIndex = KErrNotFound; - TBool found = EFalse; - - if ( aHeaders && aHeaders->Count() ) - { - // Variable to contain callID from replaces header. - TBuf8< KSVPTempStringlength > repCallId( KNullDesC8 ); - - // This is transfer session if Replaces: text is found from userheader - if ( GetCallIdFromUserHeadersL( *aHeaders, repCallId ) ) - { - SVPDEBUG1( " CSVPController::IsTransferTargetCaseL: \ - (attended) Transfer target case" ) - - if ( repCallId.Length() != 0 ) - { - // Find from SVP session array a session including same CallId - // that parsed from replace header. - for ( TInt v = 0; v < iSessionArray.Count() && !found; v++ ) - { - SVPDEBUG2( " CSVPController::IsTransferTargetCaseL v=%d", v ) - - TBuf8< KSVPTempStringlength > holdCallId( KNullDesC8 ); - TDesC8* callid2 = iSessionArray[v]->CallId(); - - if ( callid2 ) - { - TInt index = callid2->Find( KSVPCallId_replaces ); - holdCallId.Append( - callid2->Mid( index + KSVPCallId_replaces().Length() ) ); - - SVPDEBUG2( "CSVPController::IsTransferTargetCaseL: SesState: %d", - iSessionArray[v]->State() ) - - if ( repCallId == holdCallId && - MCCPCallObserver::ECCPStateDisconnecting != - iSessionArray[v]->State() ) - { - iHoldCallIndex = v; - } - } - } - - if ( KErrNotFound == iHoldCallIndex ) - { - SVPDEBUG1("CSVPController::IsTransferTargetCaseL: \ - sessions or CallIds does not match, leave !!!" ) - User::Leave( KErrNotSupported ); - } - } - else - { - SVPDEBUG1("CSVPController::IsTransferTargetCaseL: \ - Transfer session but CallId wasn't found, leave !!!" ) - User::Leave( KErrNotSupported ); - } - } - else - { - TSupplementaryServicesEvent restrictEvent = - iSuppServices->CheckRestrictionsL( *aHeaders ); - - if ( ESVPSSDoNotDisturb == restrictEvent ) - { - User::Leave( KSVPErrDnDRejection ); - } - if ( ESVPSSAnonymousBarring == restrictEvent ) - { - User::Leave( KSVPErrAnonymousCallRejection ); - } - SVPDEBUG1(" CSVPController::IsTransferTargetCaseL: \ - Normal incoming case"); - } - } - - SVPDEBUG2( "CSVPController::IsTransferTargetCaseL Out iHoldCallIndex: %d", - iHoldCallIndex ) - } - -// -------------------------------------------------------------------------- -// CSVPController::IsPreconditionRequired -// Check if Require header contains precondition and that Supported header -// includes option tag 100rel, providing support for PRACK's -// -------------------------------------------------------------------------- -TBool CSVPController::IsPreconditionRequired( CDesC8Array& aHeaders ) - { - SVPDEBUG1( "CSVPController::IsPreconditionRequired In" ) - - TInt count = aHeaders.MdcaCount(); - TBool require = EFalse; - TBool supported = EFalse; - while ( count-- ) - { - TPtrC8 tmpHeader = aHeaders.MdcaPoint( count ); - if ( KErrNotFound != tmpHeader.Find( KSVPRequire ) && !require ) - { - // "Require:" found - SVPDEBUG1( "CSVPController::IsPreconditionRequired 'Require-header' found" ) - - if ( tmpHeader.FindF( KSVPPrecondition ) ) - { - // "precondition" found in Require header field - SVPDEBUG1( "CSVPController::IsPreconditionRequired 'precondition' found" ) - require = ETrue; - } - } - else if ( KErrNotFound != tmpHeader.Find( KSVPSupported ) && !supported ) - { - // "Supported:" found - SVPDEBUG1( "CSVPController::IsPreconditionRequired 'Supported-header' found" ) - - if ( tmpHeader.FindF( KSVP100rel ) ) - { - // "100rel" found in Supported header field - SVPDEBUG1( "CSVPController::IsPreconditionRequired '100rel' found" ) - supported = ETrue; - } - } - } - if ( require && supported ) - { - SVPDEBUG1( "CSVPController::IsPreconditionRequired return ETrue" ) - return ETrue; - } - SVPDEBUG1( "CSVPController::IsPreconditionRequired return EFalse" ) - return EFalse; - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckHeadersData -// Check and store data (FromHeader, ToHeader, CallId) from the headers -// to the SessionBase. -// --------------------------------------------------------------------------- -// -void CSVPController::CheckHeadersData( CSVPSessionBase* aSVPSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::CheckHeadersData In" ) - - TRAPD( stringErr, SIPStrings::OpenL() ); - - if ( KErrNone == stringErr ) - { - // get headers - CDesC8Array* headers = aContainer->GetHeaders(); - RStringF fromHdr = SIPStrings::StringF(SipStrConsts::EFromHeader); - RStringF fromCompHdr = SIPStrings::StringF(SipStrConsts::EFromHeaderCompact); - - RStringF toHdr = SIPStrings::StringF(SipStrConsts::EToHeader); - RStringF toCompHdr = SIPStrings::StringF(SipStrConsts::EToHeaderCompact); - - RStringF callidHdr = SIPStrings::StringF(SipStrConsts::ECallIDHeader); - RStringF callidCompHdr = SIPStrings::StringF(SipStrConsts::ECallIDHeaderCompact); - - RStringF cSeqHdr = SIPStrings::StringF(SipStrConsts::ECSeqHeader); - - if ( headers ) - { - TBool fromFound( EFalse ); - TBool toFound( EFalse ); - TBool callIdFound( EFalse ); - TBool cSeqFound( EFalse ); - - for( TInt i = 0;i < headers->MdcaCount();i++ ) - { - TPtrC8 tmpHeader = headers->MdcaPoint( i ); - TInt colonMark = tmpHeader.FindF( KSVPCln ); - - SVPDEBUG2( "CSVPController::CheckHeadersData colonMark=%d", colonMark ) - - TInt fromHdrPos = tmpHeader.FindF( fromHdr.DesC() ); - TInt fromCompHdrPos = tmpHeader.FindF( fromCompHdr.DesC() ); - - TInt toHdrPos = tmpHeader.FindF( toHdr.DesC() ); - TInt toCompHdrPos = tmpHeader.FindF( toCompHdr.DesC() ); - - TInt callidHdrPos = tmpHeader.FindF( callidHdr.DesC() ); - TInt callidCompHdrPos = tmpHeader.FindF( callidCompHdr.DesC() ); - - TInt cSeqHdrPos = tmpHeader.FindF( cSeqHdr.DesC() ); - - // Header name is separeted by colonmark from header body. - // There might be space between name and colonmark. - - if ( !fromFound && - ( (KErrNotFound < fromHdrPos && fromHdrPos < colonMark) || - (KErrNotFound < fromCompHdrPos && fromCompHdrPos < colonMark ) ) ) - { - fromFound = ETrue; - aSVPSession->SetFromHeader( headers->MdcaPoint( i ) ); - } - else if ( !toFound && - ( (KErrNotFound < toHdrPos && toHdrPos < colonMark) || - (KErrNotFound < toCompHdrPos && toCompHdrPos < colonMark ) ) ) - { - toFound = ETrue; - aSVPSession->SetToHeader( headers->MdcaPoint( i ) ); - } - else if ( !callIdFound && - ( (KErrNotFound < callidHdrPos && callidHdrPos < colonMark) || - (KErrNotFound < callidCompHdrPos && callidCompHdrPos < colonMark ) ) ) - { - callIdFound = ETrue; - aSVPSession->SetCallId( headers->MdcaPoint( i ) ); - } - else if ( !cSeqFound && - KErrNotFound < cSeqHdrPos && cSeqHdrPos < colonMark ) - { - cSeqFound = ETrue; - aSVPSession->SetCSeqHeader( headers->MdcaPoint( i ) ); - } - } - } - - SIPStrings::Close(); - delete headers; - headers = NULL; - } - else - { - SVPDEBUG2( "CSVPController::CheckHeadersData stringErr=%d", stringErr ) - } - - SVPDEBUG1( "CSVPController::CheckHeadersData Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckContactData -// Check and store contact data from the headers to the MoSession -// --------------------------------------------------------------------------- -// -TInt CSVPController::CheckContactData( CSVPSessionBase* aSVPSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::CheckContactData In" ) - - TInt count( 0 ); - TRAPD( stringErr, SIPStrings::OpenL() ); - - if ( KErrNone == stringErr && aSVPSession->IsMobileOriginated() ) - { - CDesC8Array* headers = aContainer->GetHeaders(); - - if ( headers ) - { - RStringF contactHdr = SIPStrings::StringF(SipStrConsts::EContactHeader); - RStringF contactHdrComp = SIPStrings::StringF(SipStrConsts::EContactHeaderCompact); - - CSVPMoSession* moSession = static_cast< CSVPMoSession* >( aSVPSession ); - moSession->ResetForwardAddressChoices(); - - TInt ret( 0 ); - for( TInt i( 0 ); i < headers->MdcaCount(); i++ ) - { - TPtrC8 tmpHeader = headers->MdcaPoint( i ); - TInt colonMark = tmpHeader.FindF( KSVPCln ); - TPtrC8 left = tmpHeader.Left( colonMark ); // string until to first colon mark - - if ( left.CompareF( contactHdr.DesC() ) == KErrNone || - left.CompareF( contactHdrComp.DesC() ) == KErrNone ) - { - SVPDEBUG1( "CSVPController::CheckContactData - Contact header found" ) - - // Get the remaining part of the contact header string and - // send it to mo session for parsing - TPtrC8 right = tmpHeader.Right( - tmpHeader.Length() - left.Length() - 1 ); - - TRAPD( addErr, ret = moSession->AddForwardAddressL( right ) ); - if (KErrNone == addErr) - { - count = count + ret; - } - else - { - SVPDEBUG2( "CSVPController::CheckContactData: addErr = %d", addErr ) - } - } - } - } - else - { - SVPDEBUG1( "CSVPController::CheckContactData No headers" ) - } - - SIPStrings::Close(); - delete headers; - headers = NULL; - } - else - { - SVPDEBUG2( "CSVPController::CheckContactData stringErr=%d", stringErr ) - } - - SVPDEBUG2( "CSVPController::CheckContactData Out return=%d", count ) - return count; - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingUpdate -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingUpdate( - CMceSession& aOrigSession, - CMceInSession* aUpdatedSession, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::IncomingUpdate In" ) - - iContainer = *aContainer; - const TInt sessionIndex = FindSVPSession( aOrigSession ); - - if ( KErrNotFound != sessionIndex ) - { - SVPDEBUG1( "CSVPController::IncomingUpdate - Session found" ) - - // handle RE-INVITE without SDP - if ( !aUpdatedSession->Streams().Count() ) - { - SVPDEBUG1( "CSVPController::IncomingUpdate No streams present" ) - - // this call sets iEmptyReInvite flag to ETrue for session, - // flag prevents "ghots session" to be seen on UI - // when empty Re-Invite is received - iSessionArray[ sessionIndex ]->SetEmptyReInvite(); - - - #ifdef _DEBUG - - TRAPD( noSdpErr, IncomingUpdateNoSdpHandlerL( sessionIndex, - aUpdatedSession ) ); - - SVPDEBUG2( "CSVPController::IncomingUpdate trapped: %d", noSdpErr ) - - #else // _UREL - - TRAP_IGNORE( IncomingUpdateNoSdpHandlerL( - sessionIndex, aUpdatedSession ) ) - - #endif // _DEBUG - } - - else - { - SVPDEBUG1( "CSVPController::IncomingUpdate - Normal case" ) - IncomingNormalUpdate( sessionIndex, - aOrigSession, aUpdatedSession ); - } - - SVPDEBUG1( "CSVPController::IncomingUpdate - Handled" ) - } - else if ( iEmergencySession && - aUpdatedSession && - aUpdatedSession->Streams().Count() ) - { - // Handle emergency hold - TRAPD( error, iEmergencySession->IncomingRequestL( - aUpdatedSession, iContainer ) ); - - if ( error ) - { - SVPDEBUG2( "CSVPController::IncomingUpdate, emergency error=%d", - error ) - } - } - - SVPDEBUG1( "CSVPController::IncomingUpdate Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingNormalUpdate -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingNormalUpdate( TInt aSessionIndex, - CMceSession& aOrigSession, - CMceInSession* aUpdatedSession ) - { - SVPDEBUG1( "CSVPController::IncomingNormalUpdate In" ) - - TInt err = iSessionArray[ aSessionIndex ]->IncomingRequest( - *aUpdatedSession ); - - if ( KErrSVPHoldNotHoldRequest == err ) - { - SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Not Hold/Resume" ) - - if ( iSessionArray[ aSessionIndex ]->HasHoldController() && - KSVPHoldConnectedStateIndex != iSessionArray[ aSessionIndex ]-> - HoldController().HoldState() ) - { - // Hold is active; must update MCE streams state - // correspondingly - TRAP( err, iSessionArray[ aSessionIndex ]->HoldController(). - RefreshHoldStateL() ); - SVPDEBUG2( "CSVPController::IncomingNormalUpdate - Err: %d", err ) - } - - TRAP( err, UpdateSessionL( aOrigSession, *aUpdatedSession ) ); - - SVPDEBUG2( "CSVPController::IncomingNormalUpdate - Updated err: %d", - err ) - } - else if ( iDtmfStringSending ) - { - SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Dtmf sending will be stopped" ) - // send stop event to the previous character in string - // Default tone char - TChar dtmfToneChar( '0' ); - - iSessionArray[ aSessionIndex ]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceStop, - KErrNone, - dtmfToneChar ); - - // send sequence stop event - iSessionArray[ aSessionIndex ]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, - KErrNone, - dtmfToneChar ); - - // sequence complete, clear flags - iDtmfStringSending = EFalse; - iFirstDtmfSent = EFalse; - - SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Dtmf sending stopped" ) - } - else - { - SVPDEBUG2( "CSVPController::IncomingNormalUpdate - IncomingRequest err: %d", err ) - } - - iSessionArray[ aSessionIndex ]->SetUpdatedSession( aUpdatedSession ); - - SVPDEBUG1( "CSVPController::IncomingNormalUpdate Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingUpdateNoSdpHandlerL -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingUpdateNoSdpHandlerL( TInt aSessionIndex, - CMceInSession* aUpdatedSession ) - { - SVPDEBUG1( "CSVPController::IncomingUpdateNoSdpHandlerL In" ) - if ( iRtpObserver ) - { - iRtpObserver->ResetSessionInObserving( iSessionArray[ aSessionIndex ] ); - } - // set updated session to SVP, ownership is transferred - // old session is obsolete - iSessionArray[ aSessionIndex ]->SetUpdatedSession( aUpdatedSession ); - - // construct audio streams again, adding all the supported codecs - iSessionArray[ aSessionIndex ]->ConstructAudioStreamsL(); - - // finally update the session - aUpdatedSession->UpdateL(); - - SVPDEBUG1( "CSVPController::IncomingUpdateNoSdpHandlerL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::UpdateSessionL -// --------------------------------------------------------------------------- -// -void CSVPController::UpdateSessionL( CMceSession& aOrigSession, - CMceInSession& aUpdatedSession ) - { - SVPDEBUG1( "CSVPController::UpdateSessionL In" ) - - __ASSERT_ALWAYS( &aOrigSession, User::Leave( KErrArgument ) ); - __ASSERT_ALWAYS( &aUpdatedSession, User::Leave( KErrArgument ) ); - - CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); - RPointerArray< CRCSEProfileEntry > voipProfiles; - CleanupResetAndDestroy< RPointerArray< CRCSEProfileEntry > >::PushL( - voipProfiles ); - - reg->FindBySIPProfileIdL( aOrigSession.Profile(), voipProfiles ); - - TInt keepAliveTime = 0; - TInt index = FindSVPSession( aOrigSession ); - if ( KErrNotFound != index ) - { - keepAliveTime = iSessionArray[ index ]->GetKeepAliveTime(); - __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrTotalLossOfPrecision ) ); - iRtpObserver->ResetSessionInObserving( iSessionArray[ index ] ); - } - - // flag prevents wrong handling after SessionStateChanged -callback - iSessionUpdateOngoing = ETrue; - - // sets MMF priorities and sets codec specific settings - CheckStreamsL( *voipProfiles[ 0 ], aUpdatedSession, keepAliveTime, - iSessionUpdateOngoing ); - CleanupStack::PopAndDestroy( 2, reg ); - - SVPDEBUG1( "CSVPController::UpdateSessionL - Checked" ) - - aUpdatedSession.UpdateL(); - SVPDEBUG1( "CSVPController::UpdateSessionL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingRefer -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingRefer( CMceInRefer* aRefer, - const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::IncomingRefer In" ) - - // IncomingReferHandlerL is used to handle possible leave - SVPDEBUG1( "CSVPController::IncomingRefer IncomingReferHandlerL" ) - TRAPD( err, IncomingReferHandlerL( aRefer, aReferTo, aContainer ) ); - - if ( err ) - { - SVPDEBUG2("CSVPController::IncomingRefer: err: %d", err ) - // TRAP is used because of RejectL might leave. - TRAP( err, aRefer->RejectL() ); - - if ( err ) - { - SVPDEBUG2("CSspController::IncomingRefer: RejectL err: %d", err ) - } - } - - SVPDEBUG1( "CSVPController::IncomingRefer Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingReferHandlerL -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingReferHandlerL( CMceInRefer* aRefer, - const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::IncomingReferHandlerL In" ) - - __ASSERT_ALWAYS( aRefer, User::Leave( KErrArgument ) ); - - iContainer = *aContainer; - TInt sessionIndex = FindSVPSession( *aRefer->AssociatedSession() ); - - if ( KErrNotFound != sessionIndex ) - { - SVPDEBUG2( "CSVPController::InRefHL: AssoSes OK,ind=%d", - sessionIndex ) - - iSessionArray[ sessionIndex ]->IncomingReferL( - aRefer, aReferTo, aContainer ); - - if ( iSessionArray[ sessionIndex ]->IsAttended() ) - { - SVPDEBUG1( "CSVPController::InRefHL: - Attended case" ) - } - else - { - SVPDEBUG1( "CSVPController::InRefHL: - Unattended case" ) - // Create a new session - CreateNewTransferSessionL( sessionIndex, EFalse ); - } - } - else - { - SVPDEBUG1( "CSVPController::InRefHL: Session not Found!!" ) - User::Leave( KErrNotFound ); - } - - SVPDEBUG1( "CSVPController::IncomingReferHandlerL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::CreateNewTransferSessionL -// --------------------------------------------------------------------------- -// -void CSVPController::CreateNewTransferSessionL( TInt aSessionIndex, - TBool aAttended ) - { - SVPDEBUG1( "CSVPController::CreateNewTransferSessionL In" ) - - iIncomingReferCallIndex = aSessionIndex; - // Create a new session - // fetch SIP profile ID from VoIP profiles - RPointerArray< CRCSEProfileEntry > entryArray; - CleanupResetAndDestroy< - RPointerArray >::PushL( entryArray ); //CS: 1 - - CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); //CS:2 - - const CCCPCallParameters& callParams = iSessionArray[ aSessionIndex ]->Parameters(); - SVPDEBUG2(" CSVPController::CNTSL: iServiceId = %d", callParams.ServiceId() ) - - // Get VoIP profile by service id - reg->FindByServiceIdL( callParams.ServiceId(), entryArray ); - // Take first entry from array - CRCSEProfileEntry* entry = entryArray[0]; - - // array for provisioned data - CDesC8ArrayFlat* userAgentHeaders = new( ELeave )CDesC8ArrayFlat( 4 ); - CleanupStack::PushL( userAgentHeaders ); - - // variable for storing security status - TUint32 securityStatus = 0; - - // set provisioning data - SVPDEBUG1( "CSVPController::CNTSL: Set provisioning data..." ) - TRAP_IGNORE( iSVPUtility->SetProvisioningDataL( - *entry, - *userAgentHeaders, - securityStatus, - iTerminalType, - iWlanMacAddress ) ); - - // only one sip profile per voip profile - TInt sipProfileId = entry->iIds[ 0 ].iProfileId; - SVPDEBUG2( "CSVPController::CNTSL: sipProfileId=%d", sipProfileId ) - - if ( KSVPStatusNonSecure != securityStatus ) - { - // If preferred sec is 1 or 2, we check also secure mechanism of sip profile. - // create SIP and ProfileRegistry for URI handling - CSIP* sip = CSIP::NewL( KSVPUid, *this ); - CleanupStack::PushL( sip ); - SVPDEBUG1( "CSVPController::CNTSL: sip CREATED" ) - - CSIPProfileRegistry* sipProfileRegistry = - CSIPProfileRegistry::NewL( *sip, *this ); - CleanupStack::PushL( sipProfileRegistry ); - - SVPDEBUG1( "CSVPController::CNTSL: sipProfileRegistry CREATED" ) - - // retrieve SIP profile by using sip profile id - CSIPProfile* profile = sipProfileRegistry->ProfileL( sipProfileId ); - CleanupStack::PushL( profile ); - - // set secure status to 0 if no security mechanism found from SIP profile - iSVPUtility->ResolveSecurityMechanismL( *profile, securityStatus ); - - CleanupStack::PopAndDestroy( 3, sip ); // profile, sipProfileRegistry, sip - } - - // set transfer data - SVPDEBUG1( "CSVPController::CNTSL: Set transfer data..." ) - iSessionArray[ aSessionIndex ]->SetTransferDataL( - userAgentHeaders, securityStatus ); - - SVPDEBUG3( "CSVPController::CNTSL: Header count:%d, sec status:%d", - userAgentHeaders->Count(), securityStatus ) - - CSVPMoSession* moSessionTemp = NULL; - - // In attended and unattended transfer case recipient is solved here - SVPDEBUG1( "CSVPController::CNTSL: (Un)Attended, create new mo session" ) - const TDesC& referTo = iSessionArray[ aSessionIndex ]->TransferTarget(); - // "convert" recpient to 8-bit format - HBufC8* recipient = HBufC8::NewLC( referTo.Length() ); - recipient->Des().Copy( referTo ); - - moSessionTemp = CSVPMoSession::NewL( *iMceManager, - *recipient, - *entry, - callParams, - iContainer, - *this, - *iSVPUtility, - *iRtpObserver, - securityStatus, - userAgentHeaders ); - - CleanupStack::PopAndDestroy( recipient ); - CleanupStack::PushL( moSessionTemp ); - - // dtmf and rtp observervers are set - moSessionTemp->SetDtmfObserver( iSessionArray[ aSessionIndex ]->DtmfObserver() ); - iRtpObserver->AddSessionForObservingL( moSessionTemp ); - - // created SVP session is appended to session array - iSessionArray.AppendL( moSessionTemp ); - CleanupStack::Pop( moSessionTemp ); - CleanupStack::Pop( userAgentHeaders ); - CleanupStack::PopAndDestroy( 2, &entryArray ); - - // set CCP session observer to SVP session - SVPDEBUG1( "CSVPController::CNTSL: AddObserverL" ) - moSessionTemp->AddObserverL( iSessionArray[ aSessionIndex ]->GetCCPSessionObserver() ); - - //set CCP supplementary services events observer to SVP session - SVPDEBUG1( "CSVPController::CNTSL: AddSsObserverL" ) - moSessionTemp->SetSsObserver( iSessionArray[ aSessionIndex ]->GetSsObserver() ); - - SVPDEBUG1( "CSVPController::CNTSL: callcreated, send to CCP" ) - ExecCbCallCreated( moSessionTemp, iSessionArray[ aSessionIndex ], aAttended ); - - SVPDEBUG1( "CSVPController::CreateNewTransferSessionL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::HandleForwardEvent -// --------------------------------------------------------------------------- -// -void CSVPController::HandleCallForward( TInt aStatusCode, - TInt aSessionIndex, TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::HandleForwardEvent In" ) - SVPDEBUG2( "CSVPController::HandleForwardEvent aStatusCode=%d", aStatusCode ) - - if ( !iSessionArray[ aSessionIndex ]->IsMobileOriginated() ) - { - iSessionArray[ aSessionIndex ]-> - GetCCPSessionObserver().ErrorOccurred( ECCPErrorNotReached, - iSessionArray[ aSessionIndex ] ); - } - else - { - CSVPMoSession* session = static_cast< CSVPMoSession* >( - iSessionArray[ aSessionIndex ] ); - - switch ( aStatusCode ) - { - case KSVPMultipleChoicesVal: // 300 - case KSVPMovedPermanentlyVal: // 301 - { - // Get contact headers and notify - TInt count = CheckContactData( session, aContainer ); - - if ( 0 < count ) - { - session->NotifyForwardEvent( aStatusCode ); - } - else - { - session->GetCCPSessionObserver().ErrorOccurred( - ECCPErrorNotReached, - session ); - } - break; - } - case KSVPMovedTemporarilyVal: // 302 - { - // Just notify, this call forward is handled automatically by mce - session->NotifyForwardEvent( aStatusCode ); - session->GetCCPSessionObserver(). - CallStateChanged( MCCPCallObserver::ECCPStateForwarding, - session ); - break; - } - default: - { - SVPDEBUG1( "CSVPController::HandleForwardEvent: unknown code" ) - session->GetCCPSessionObserver().ErrorOccurred( - ECCPErrorNotReached, - session ); - } - } - } - - SVPDEBUG1( "CSVPController::HandleForwardEvent Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::StreamStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::StreamStateChanged( CMceMediaStream& aStream ) - { - SVPDEBUG1("CSVPController::StreamStateChanged In" ) - - if ( &aStream ) - { - if ( !iEmergencySession ) - { - const TInt index = FindSVPSession( *aStream.Session() ); - if ( KErrNotFound != index ) - { - iSessionArray[ index ]->HandleStreamStateChange( aStream ); - } - - SVPDEBUG2( "CSVPController::StreamStateChanged index: %d", index ) - } - else // Emergency session - { - iEmergencySession->StreamStateChanged( aStream ); - } - } - else - { - SVPDEBUG1( "CSVPController::StreamStateChanged, faulty arguments" ) - } - - SVPDEBUG1("CSVPController::StreamStateChanged Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::StreamStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::StreamStateChanged( CMceMediaStream& aStream, - CMceMediaSink& aSink ) - { - SVPDEBUG1( "CSVPController::StreamStateChanged SINK In" ) - - if ( &aStream && &aSink ) - { - SVPDEBUG2( "CSVPController::StreamStateChanged SINK Stream State: %d", aStream.State() ) - SVPDEBUG2( "CSVPController::StreamStateChanged SINK Sink IsEnabled: %d", aSink.IsEnabled() ) - - if ( !iEmergencySession ) - { - const TInt index = FindSVPSession( *aStream.Session() ); - - if ( KErrNotFound != index ) - { - iSessionArray[ index ]->HandleStreamStateChange( aStream, aSink ); - } - - SVPDEBUG2( "CSVPController::StreamStateChanged SINK index: %d", index ) - } - else // Emergency session - { - iEmergencySession->StreamStateChanged( aStream ); - } - } - else - { - SVPDEBUG1( "CSVPController::StreamStateChanged SINK, faulty arguments" ) - } - - SVPDEBUG1( "CSVPController::StreamStateChanged SINK Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::StreamStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::StreamStateChanged( CMceMediaStream& aStream, - CMceMediaSource& aSource ) - { - SVPDEBUG1( "CSVPController::StreamStateChanged SOURCE In" ) - - if ( &aStream && &aSource ) - { - SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE Stream State: %d", aStream.State() ) - SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE Source IsEnabled: %d", aSource.IsEnabled() ) - - if ( !iEmergencySession ) - { - const TInt index = FindSVPSession( *aStream.Session() ); - if ( KErrNotFound != index ) - { - iSessionArray[ index ]->HandleStreamStateChange( aStream, aSource ); - } - - SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE index: %d", index ) - } - else // Emergency session - { - iEmergencySession->StreamStateChanged( aStream ); - } - - } - - SVPDEBUG1( "CSVPController::StreamStateChanged SOURCE Out" ) - } - - -// from ConvergedCallProvider -// --------------------------------------------------------------------------- -// CSVPController::NewEmergencyCallL -// --------------------------------------------------------------------------- -// -MCCPEmergencyCall* CSVPController::NewEmergencyCallL( - const TUint32 /*aServiceId*/, - const TDesC& aAddress, - const MCCPCallObserver& aObserver ) - { - SVPDEBUG1( "CSVPController::NewEmergencyCallL In" ) - - // Retrieve available VoIP and IAP IDs - if ( 0 == iEmergencyProfileIds.Count() && 0 == iEmergencyIapIds.Count() ) - { - CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:1 - CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS:2 - CSIPProfileRegistry* sipProfileRegistry = CSIPProfileRegistry::NewLC( - *sip, *this ); // CS:3 - - // Get all VoIP profile IDs into an array - RArray< TUint32 > voipProfileIds; - CleanupClosePushL( voipProfileIds ); //CS: 4 - reg->GetAllIdsL( voipProfileIds ); - - // Sort the VoIP profile array so that registered profiles are first - for ( TInt i = 0; i < voipProfileIds.Count(); i++ ) - { - TBool registered( EFalse ); - CRCSEProfileEntry* entry = CRCSEProfileEntry::NewLC(); // CS:5 - reg->FindL( voipProfileIds[i], *entry ); - // There is only one (or zero) SIP profile per VoIP profile. - // If profileId is not found, - // CSVPEmergencySession::ConstructL will handle the error - if ( 0 < entry->iIds.Count() ) - { - SVPDEBUG2( "CSVPController::NewEmergencyCallL, SIP Id count:%d", - entry->iIds.Count() ) - CSIPProfile* sipProfile = sipProfileRegistry->ProfileL( - entry->iIds[0].iProfileId ); - sipProfile->GetParameter( KSIPProfileRegistered, registered ); - delete sipProfile; - } - CleanupStack::PopAndDestroy( entry ); // CS:4 - if ( registered ) - { - // Move registered VoIP profile IDs to the front - iEmergencyProfileIds.Insert( voipProfileIds[i], 0 ); - } - else - { - iEmergencyProfileIds.Append( voipProfileIds[i] ); - } - } - - CleanupStack::PopAndDestroy( 4, reg ); - // CS:0 voipProfileIds, sipProfileRegistry, sip, reg - - // Request and wait for IAP IDs - CSVPEmergencyIapProvider* iapProvider = - CSVPEmergencyIapProvider::NewLC( - CActive::EPriorityStandard ); // CS:1 - iapProvider->RequestIapIds( iEmergencyIapIds ); - CleanupStack::PopAndDestroy( iapProvider ); // CS:0 - } - - SVPDEBUG2("CSVPController::NewEmergencyCallL, VoIP count:%d", - iEmergencyProfileIds.Count() ) - SVPDEBUG2("CSVPController::NewEmergencyCallL, IAP count:%d", - iEmergencyIapIds.Count() ) - - // Define last try - TBool isLastId( EFalse ); - - if ( ( 0 == iEmergencyProfileIds.Count() && - 1 == iEmergencyIapIds.Count() ) || - ( 1 == iEmergencyProfileIds.Count() && - 0 == iEmergencyIapIds.Count() ) - ) - { - isLastId = ETrue; - SVPDEBUG1("CSVPController::NewEmergencyCallL, last ID"); - } - - // Create session - CSVPEmergencySession* emergencySession = NULL; - - if ( iEmergencyProfileIds.Count() ) - { - // Create emergency session with VoIP ID - TRAPD( err, emergencySession = CSVPEmergencySession::NewL( - *iMceManager, - iEmergencyProfileIds[0], - aAddress, - aObserver, - *iSVPUtility, - isLastId ) ) - - if ( err ) - { - // Create dummy session for session release - emergencySession = CSVPEmergencySession::NewL( - *iMceManager, - iEmergencyProfileIds[0], - aAddress, - aObserver, - *iSVPUtility, - isLastId, - ETrue ); - } - - // Update profile array - iEmergencyProfileIds.Remove( 0 ); - } - else if ( iEmergencyIapIds.Count() ) - { - // Create emergency session with IAP ID - TRAPD( err, emergencySession = CSVPEmergencySession::NewL( - *iMceManager, - aAddress, - aObserver, - *iSVPUtility, - iEmergencyIapIds[0], - isLastId ) ) - - if ( err ) - { - // Create dummy session for session release - emergencySession = CSVPEmergencySession::NewL( - *iMceManager, - aAddress, - aObserver, - *iSVPUtility, - iEmergencyIapIds[0], - isLastId, - ETrue ); - } - - // Update IAP array - iEmergencyIapIds.Remove( 0 ); - } - else - { - User::Leave( KErrNotFound ); - } - - // save emergency session to controller - iEmergencySession = emergencySession; - - if ( iCCPDtmfObserver ) - { - SVPDEBUG1( "CSVPController::NewEmergencyCallL setting DTMFObserver" ) - iEmergencySession->SetDtmfObserver( *iCCPDtmfObserver ); - } - - SVPDEBUG1( "CSVPController::NewEmergencyCallL Out" ) - // return pointer to CCP emergency call object - return emergencySession; - } - -// --------------------------------------------------------------------------- -// CSVPController::NewConferenceL -// --------------------------------------------------------------------------- -// -MCCPConferenceCall* CSVPController::NewConferenceL( - const TUint32 /* aServiceId */, - const MCCPConferenceCallObserver& /*aObserver*/ ) - { - return NULL; - } - -// --------------------------------------------------------------------------- -// CSVPController::AcceptTransfer -// --------------------------------------------------------------------------- -// -void CSVPController::AcceptTransfer( TBool /*aAccept*/ ) - { - SVPDEBUG1( "CSVPController::AcceptTransfer In" ) - SVPDEBUG1( "CSVPController::AcceptTransfer Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::ForwardCallToAddressL -// --------------------------------------------------------------------------- -// -TInt CSVPController::ForwardCallToAddressL( const TInt /*aIndex*/ ) - { - return NULL; - } - -// --------------------------------------------------------------------------- -// CSVPController::Caps -// --------------------------------------------------------------------------- -// -TUint32 CSVPController::Caps() const - { - return 0; - } - -// --------------------------------------------------------------------------- -// CSVPController::DTMFProvider -// --------------------------------------------------------------------------- -// -MCCPDTMFProvider* CSVPController::DTMFProviderL( - const MCCPDTMFObserver& aObserver ) - { - SVPDEBUG1( "CSVPController::DTMFProviderL In" ) - - iCCPDtmfObserver = &aObserver; - - TInt sessions = iSessionArray.Count(); - while ( sessions ) - { - sessions--; - iSessionArray[ sessions ]->SetDtmfObserver( aObserver ); - - SVPDEBUG2( "CSVPController::DTMFProviderL sessions: %d", sessions ) - } - - if ( iEmergencySession ) - { - iEmergencySession->SetDtmfObserver( aObserver ); - } - - SVPDEBUG1( "CSVPController::DTMFProviderL Out" ) - return this; - } - - -// --------------------------------------------------------------------------- -// CSVPController::ExtensionProvider -// --------------------------------------------------------------------------- -// -MCCPExtensionProvider* CSVPController::ExtensionProviderL( - const MCCPExtensionObserver& /*aObserver*/ ) - { - return NULL; - } - -// dtmf provider - -// --------------------------------------------------------------------------- -// CSVPController::CancelDtmfStringSending -// --------------------------------------------------------------------------- -// -TInt CSVPController::CancelDtmfStringSending() - { - SVPDEBUG1( "CSVPController::CancelDtmfStringSending In" ) - - TInt err( KErrNotSupported ); - // find active session - - TInt sesCount = iSessionArray.Count(); - CSVPSessionBase* session = NULL; - while ( sesCount ) - { - sesCount--; - session = iSessionArray[ sesCount ]; - - if ( SVPAudioUtility::DtmfActionCapableSession( *session ) ) - { - err = session->CancelDtmfStringSending(); - } - SVPDEBUG3( "CSVPController::CancelDtmfStringSending sesCount: %d, err: %d", - sesCount, err ) - session = NULL; - } - - if ( iEmergencySession && - SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) ) - { - err = iEmergencySession->CancelDtmfStringSending(); - } - - SVPDEBUG2("CSVPController::CancelDtmfStringSending Out return=%d", err ) - iDtmfStringSending = EFalse; - iFirstDtmfSent = EFalse; - return err; - } - -// --------------------------------------------------------------------------- -// CSVPController::StartDtmfTone -// --------------------------------------------------------------------------- -// -TInt CSVPController::StartDtmfTone( const TChar aTone ) - { - SVPDEBUG1( "CSVPController::StartDtmfTone In" ) - - TInt err( KErrNotSupported ); - - // Save DTMF tone for later use in outband dtmf start/stop events - iDtmfTone = aTone; - // Send the tone to all sessions, but check mute and hold cases where session must - // be in 'connected' state in order to send DTMF's. Session will then - // discriminate between inband and outband DTMF's. - TInt sesCount = iSessionArray.Count(); - CSVPSessionBase* session = NULL; - while ( sesCount ) - { - sesCount--; - session = iSessionArray[ sesCount ]; - // Checking hold and mute status - if ( SVPAudioUtility::DtmfActionCapableSession( *session ) && - !session->IsSessionMuted() ) - { - err = session->StartDtmfTone( aTone ); - } - SVPDEBUG3( "CSVPController::StartDtmfTone sesCount: %d, err: %d", - sesCount, err ) - session = NULL; - } - - if ( iEmergencySession && - SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) ) - { - err = iEmergencySession->StartDtmfTone( aTone ); - } - - SVPDEBUG2("CSVPController::StartDtmfTone Out return=%d", err ) - return err; - } - -// --------------------------------------------------------------------------- -// CSVPController::StopDtmfTone -// --------------------------------------------------------------------------- -// -TInt CSVPController::StopDtmfTone() - { - SVPDEBUG1( "CSVPController::StopDtmfTone In" ) - - TInt err( KErrNotSupported ); - - TInt sesCount = iSessionArray.Count(); - CSVPSessionBase* session = NULL; - while ( sesCount ) - { - sesCount--; - session = iSessionArray[ sesCount ]; - - if ( SVPAudioUtility::DtmfActionCapableSession( *session ) ) - { - err = session->StopDtmfTone(); - } - SVPDEBUG3( "CSVPController::StopDtmfTone sesCount: %d, err: %d", - sesCount, err ) - session = NULL; - } - - if ( iEmergencySession && - SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) ) - { - err = iEmergencySession->StopDtmfTone(); - } - - SVPDEBUG2("CSVPController::StopDtmfTone Out return=%d", err ) - return err; - } - -// --------------------------------------------------------------------------- -// CSVPController::SendDtmfToneString -// --------------------------------------------------------------------------- -// -TInt CSVPController::SendDtmfToneString( const TDesC& aString ) - { - SVPDEBUG1( "CSVPController::SendDtmfToneString In" ) - - TInt err( KErrNotSupported ); - - delete iDtmfString; - iDtmfString = NULL; - TRAPD( errBuf, iDtmfString = HBufC::NewL( aString.Length() ) ); - if ( KErrNone != errBuf ) - { - return errBuf; - } - // Take local copy of the dtmf string to be sent - // This is needed for outband dtmf sequence start/stop event - *iDtmfString = aString; - iDtmfStringLex.Assign( *iDtmfString ); - - TInt sesCount = iSessionArray.Count(); - CSVPSessionBase* session = NULL; - - while ( sesCount ) - { - sesCount--; - session = iSessionArray[ sesCount ]; - // Checking hold and mute status - if ( SVPAudioUtility::DtmfActionCapableSession( *session ) && - !session->IsSessionMuted() ) - { - err = session->SendDtmfToneString( aString ); - if ( KErrNone == err ) - { - iDtmfStringSending = ETrue; - iFirstDtmfSent = EFalse; - } - } - SVPDEBUG3( "CSVPController::SendDtmfToneString sesCount: %d, err: %d", - sesCount, err ) - session = NULL; - } - - if ( iEmergencySession ) - { - if ( SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) ) - { - err = iEmergencySession->SendDtmfToneString( aString ); - } - iDtmfStringSending = ETrue; - iFirstDtmfSent = EFalse; - } - - SVPDEBUG2("CSVPController::SendDtmfToneString Out return=%d", err ) - return err; - } - -// --------------------------------------------------------------------------- -// CSVPController::ContinueDtmfStringSending -// --------------------------------------------------------------------------- -// -TInt CSVPController::ContinueDtmfStringSending( const TBool /*aContinue*/ ) - { - // SVP sessionbase used to implement this as only returning - // KErrNotSupported, so why not accept the situation here and just - // return KErrNotSupported. - - SVPDEBUG1( "CSVPController::ContinueDtmfStringSending KErrNotSupported" ) - return KErrNotSupported; - } - -// --------------------------------------------------------------------------- -// CSVPController::AddObserverL -// --------------------------------------------------------------------------- -// -void CSVPController::AddObserverL( const MCCPDTMFObserver& /*aObserver*/ ) - { - SVPDEBUG1( "CSVPController::AddObserverL MCCPDTMFObserver" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::RemoveObserver -// --------------------------------------------------------------------------- -// -TInt CSVPController::RemoveObserver( const MCCPDTMFObserver& /*aObserver*/ ) - { - SVPDEBUG1( "CSVPController::RemoveObserver MCCPDTMFObserver" ) - return KErrNotSupported; - } - - -// refer observer - -// --------------------------------------------------------------------------- -// CSVPController::ReferStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::ReferStateChanged( CMceRefer& aRefer, - TMceTransactionDataContainer* aContainer ) - { - SVPDEBUG1( "CSVPController::ReferStateChanged In" ) - - iContainer = *aContainer; - TInt ind = KErrNotFound; - - // loop session array and check refer - for ( TInt s = 0; s < iSessionArray.Count() && - KErrNotFound == ind; s++ ) - { - if ( iSessionArray[ s ]->IsMceRefer( aRefer ) ) - { - ind = s; - } - } - - if ( KErrNotFound != ind ) - { - SVPDEBUG2(" CSVPController::ReferStateChanged ind: %d", ind ); - TInt statusCode = iContainer.GetStatusCode(); - - iSessionArray[ ind ]->ReferStateChanged( aRefer, statusCode ); - } - - SVPDEBUG1( "CSVPController::ReferStateChanged Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::ReferConnectionStateChanged -// --------------------------------------------------------------------------- -// -void CSVPController::ReferConnectionStateChanged( CMceRefer& /*aRefer*/, - TBool /*aActive*/ ) - { - SVPDEBUG1( "CSVPController::ReferConnectionStateChanged" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::Failed -// --------------------------------------------------------------------------- -// -#ifdef _DEBUG -void CSVPController::Failed( CMceRefer& /*aRefer*/, TInt aError ) -#else -void CSVPController::Failed( CMceRefer& /*aRefer*/, TInt /*aError*/ ) -#endif // _DEBUG - { - SVPDEBUG2( "CSVPController::Failed Refer failed with error: %d", aError ) - } - - -// Mce DMTF observer -// --------------------------------------------------------------------------- -// CSVPController::DtmfToneReceived -// --------------------------------------------------------------------------- -// -void CSVPController::DtmfToneReceived( CMceSession& /*aSession*/, - CMceAudioStream& /*aStream*/, const TChar& /*aTone*/ ) - { - // Not supported - SVPDEBUG1( "CSVPController:: DtmfToneReceived - Not supported" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::DtmfEventReceived -// --------------------------------------------------------------------------- -// -void CSVPController::DtmfEventReceived( CMceSession& aSession, - CMceAudioStream& /*aStream*/, - CMceMediaSource& /*aSource*/, - TMceDtmfEvent aEvent ) - { - SVPDEBUG3( "CSVPController::DtmfEventReceived In, aEvent: %d, iDtmfStringSending: %d", - aEvent, iDtmfStringSending ) - - // find what session received the event - const TInt index = FindSVPSession( aSession ); - - if ( KErrNotFound != index ) - { - // match dtmf event - MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = - iSVPUtility->GetDtmfEvent( aEvent, iDtmfStringSending ); - - // dtmf string - if ( iDtmfStringSending ) - { - // only start event received from mce - // logic below needed so that stop events can be sent - if ( MCCPDTMFObserver::ECCPDtmfSequenceStart == dtmfEvent ) - { - if ( !iFirstDtmfSent ) - { - SVPDEBUG1( "CSVPController::DtmfEventReceived FIRST SEND" ) - - // send start - iFirstDtmfSent = ETrue; - // call back event to application - iSessionArray[ index ]-> - DtmfObserver().HandleDTMFEvent( dtmfEvent, - KErrNone, - iDtmfStringLex.Peek() ); - } - else - { - SVPDEBUG1( "CSVPController::DtmfEventReceived STOP TO PREVIOUS" ) - - // send stop event to the previous character in string - iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceStop, - KErrNone, - iDtmfStringLex.Get() ); - SVPDEBUG1("CSVPController::DtmfEventReceived START TO CURRENT"); - // send start event to the current character in string - iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( - dtmfEvent, - KErrNone, - iDtmfStringLex.Peek() ); - } - } - else - { - SVPDEBUG1( "CSVPController::DtmfEventReceived STOP TO PREVIOUS AND LAST" ) - - // send stop event to the previous character in string - iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceStop, - KErrNone, - iDtmfStringLex.Peek() ); - - SVPDEBUG1( "CSVPController::DtmfEventReceived COMPLETE" ) - - // send sequence stop event - iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, - KErrNone, - iDtmfStringLex.Peek() ); - // sequence complete, clear flags - iDtmfStringSending = EFalse; - iFirstDtmfSent = EFalse; - - delete iDtmfString; - iDtmfString = NULL; - } - } - // manual dtmf - else - { - // call back event to application - iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( - dtmfEvent, - KErrNone, - iDtmfTone ); - } - } - - else if ( iEmergencySession ) - { - const MCCPDTMFObserver& dtmfObs = iEmergencySession->DtmfObserver(); - SVPDEBUG2("CSVPController::DtmfEventReceived, %d = DtmfObserver()", &dtmfObs ) - // match dtmf event - MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = - iSVPUtility->GetDtmfEvent( aEvent, iDtmfStringSending ); - - // dtmf string - if ( iDtmfStringSending && NULL != &dtmfObs ) - { - // only start event received from mce - // logic below needed so that stop events can be sent - if ( MCCPDTMFObserver::ECCPDtmfSequenceStart == dtmfEvent ) - { - if ( !iFirstDtmfSent ) - { - SVPDEBUG1( - "CSVPController::DtmfEventReceived, emergency FIRST SEND") - - // send start - iFirstDtmfSent = ETrue; - // call back event to application - dtmfObs.HandleDTMFEvent( dtmfEvent, KErrNone, iDtmfStringLex.Peek() ); - } - else - { - SVPDEBUG1("CSVPController::DtmfEventReceived,\ - emergency STOP TO PREVIOUS") - - // send stop event to the previous character in string - dtmfObs.HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceStop, - KErrNone, - iDtmfStringLex.Get() ); - SVPDEBUG1("CSVPController::DtmfEventReceived,\ - emergency START TO CURRENT") - // send start event to the current character in string - dtmfObs.HandleDTMFEvent( - dtmfEvent, - KErrNone, - iDtmfStringLex.Peek() ); - } - } - else - { - SVPDEBUG1("CSVPController::DtmfEventReceived,\ - emergency STOP TO PREVIOUS AND LAST") - - // send stop event to the previous character in string - dtmfObs.HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfSequenceStop, - KErrNone, - iDtmfStringLex.Peek() ); - - SVPDEBUG1("CSVPController::DtmfEventReceived,\ - emergency COMPLETE") - - // send sequence stop event - dtmfObs.HandleDTMFEvent( - MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, - KErrNone, - iDtmfStringLex.Peek() ); - // sequence complete, clear flags - iDtmfStringSending = EFalse; - iFirstDtmfSent = EFalse; - - delete iDtmfString; - iDtmfString = NULL; - } - } - // manual dtmf - else if( NULL != &dtmfObs ) - { - SVPDEBUG1("CSVPController::DtmfEventReceived,\ - manual dtmf , call back event to application") - dtmfObs.HandleDTMFEvent( dtmfEvent, KErrNone, iDtmfTone ); - } - else - { - SVPDEBUG1("CSVPController::DtmfEventReceived, DtmfObs not set") - } - } - - SVPDEBUG1( "CSVPController::DtmfEventReceived Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::DtmfErrorOccured -// --------------------------------------------------------------------------- -// - void CSVPController::DtmfErrorOccured( CMceSession& aSession, - CMceAudioStream& /*aStream*/,CMceMediaSource& /*aSource*/, - TInt aError ) - { - SVPDEBUG2( "CSVPController::DtmfErrorOccured In, aError: %d", aError ) - - // find what session received the event - const TInt index = FindSVPSession( aSession ); - if ( KErrNotFound != index ) - { - // match dtmf event, unknown set as default in error case, 'tis ok? - const MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = - MCCPDTMFObserver::ECCPDtmfUnknown; - - // default tone char - TChar dtmfToneChar('0'); - - // call back error - iSessionArray[ index ]-> - DtmfObserver().HandleDTMFEvent( dtmfEvent, - aError, - dtmfToneChar ); - } - - SVPDEBUG1( "CSVPController::DtmfErrorOccured Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::FinalizeSessionCreationL -// --------------------------------------------------------------------------- -// -void CSVPController::FinalizeSessionCreationL( CSVPSessionBase* aSession ) - { - SVPDEBUG2( "CSVPController::FinalizeSessionCreationL In, aSession: 0x%x", - aSession ) - - __ASSERT_ALWAYS( aSession, User::Leave( KErrArgument ) ); - - if ( iCCPDtmfObserver ) - { - aSession->SetDtmfObserver( *iCCPDtmfObserver ); - } - - iRtpObserver->AddSessionForObservingL( aSession ); - iSessionArray.AppendL( aSession ); - - SVPDEBUG1( "CSVPController::FinalizeSessionCreationL Out" ) - } - -// --------------------------------------------------------------------------- -// CSVPController::ExecCbErrorOccurred -// --------------------------------------------------------------------------- -// -TInt CSVPController::ExecCbErrorOccurred( MCCPObserver::TCCPError aError ) - { - SVPDEBUG2( "CSVPController::ExecCbErrorOccurred In, aError=%d", aError ) - - TInt status = KErrNotFound; - - if ( iCCPMonitor ) - { - status = KErrNone; - iCCPMonitor->ErrorOccurred( aError ); - } - - SVPDEBUG2( "CSVPController::ExecCbErrorOccurred Out return=%d", status ) - return status; - } - -// --------------------------------------------------------------------------- -// CSVPController::IncomingCall -// --------------------------------------------------------------------------- -// -TInt CSVPController::ExecCbIncomingCall( MCCPCall* aCall ) - { - SVPDEBUG2( "CSVPController::ExecCbIncomingCall In, aCall= 0x%x", aCall ) - - TInt status = KErrNotFound; - - if ( iCCPMonitor ) - { - status = KErrNone; - iCCPMonitor->IncomingCall( aCall ); - } - - SVPDEBUG2( "CSVPController::ExecCbIncomingCall Out return=%d", status ) - return status; - } - -// --------------------------------------------------------------------------- -// CSVPController::ExecCbIncomingCall -// --------------------------------------------------------------------------- -// -TInt CSVPController::ExecCbIncomingCall( MCCPCall* aCall, MCCPCall& aTempCall ) - { - SVPDEBUG2( "CSVPController::ExecCbIncomingCall In, aCall= 0x%x", aCall ) - SVPDEBUG2( "CSVPController::ExecCbIncomingCall aTempCall= 0x%x", &aTempCall ) - - TInt status = KErrNotFound; - - if ( iCCPMonitor ) - { - status = KErrNone; - iCCPMonitor->IncomingCall( aCall, aTempCall ); - } - - SVPDEBUG2( "CSVPController::ExecCbIncomingCall Out return=%d", status ) - return status; - } - -// --------------------------------------------------------------------------- -// CSVPController::ExecCbCallCreated -// --------------------------------------------------------------------------- -// -TInt CSVPController::ExecCbCallCreated( MCCPCall* aNewTransferCall, - MCCPCall* aOriginator, TBool aAttended ) - { - SVPDEBUG2( "CSVPController::ExecCbCallCreated In, aNewTransferCall= 0x%x", aNewTransferCall ) - SVPDEBUG2( "CSVPController::ExecCbCallCreated aOriginator= 0x%x", aOriginator ) - SVPDEBUG2( "CSVPController::ExecCbCallCreated aAttended= %d", aAttended ) - - TInt status = KErrNotFound; - - if ( iCCPMonitor ) - { - status = KErrNone; - iCCPMonitor->CallCreated( aNewTransferCall, aOriginator, aAttended ); - } - - SVPDEBUG2( "CSVPController::ExecCbCallCreated Out return=%d", status ) - return status; - } - -// --------------------------------------------------------------------------- -// CSVPController::ParseRecipientDtmfSuffixL -// --------------------------------------------------------------------------- -// -HBufC* CSVPController::ParseRecipientDtmfSuffixL( const TDesC& aRecipient ) const - { - __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) ); - - SVPDEBUG2( "CSVPController::ParseRecipientDtmfSuffixL In, aRecipient=%S", &aRecipient ) - - HBufC* result = aRecipient.AllocLC(); // CS:1 - - TInt recipientLength = result->Length(); - if ( recipientLength ) - { - if ( IsValidDtmfRecipientL( *result ) ) - { - TInt loopCount = 0; - if ( KErrNotFound != KSVPDtmfTelNumRange().Locate( result->Des()[loopCount] ) ) - { - loopCount++; - TBool doLoop = ETrue; - do - { - if ( loopCount < recipientLength ) - { - if ( KErrNotFound != - KSVPDtmfDelimiterRange().Locate( result->Des()[loopCount] ) ) - { - TInt suffixLength = recipientLength - loopCount; - result->Des().Delete( loopCount, suffixLength ); - doLoop = EFalse; - SVPDEBUG1( - "CSVPController::ParseRecipientDtmfSuffixL, DTMF suffix removed" ) - } - else - { - loopCount++; - } - } - else - { - doLoop = EFalse; - } - } while ( doLoop ); - } - } - } - SVPDEBUG2( "CSVPController::ParseRecipientDtmfSuffixL Out, result=%S", result ) - CleanupStack::Pop( result ); // CS:0 - return result; - } - -// --------------------------------------------------------------------------- -// CSVPController::IsValidDtmfRecipientL -// --------------------------------------------------------------------------- -// -TBool CSVPController::IsValidDtmfRecipientL( const TDesC& aRecipient ) const - { - __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) ); - - SVPDEBUG1( "CSVPController::IsValidDtmfRecipientL In" ) - - TBool result = ETrue; - if ( aRecipient.Length() ) - { - TBool loopDo = ETrue; - TInt loopCount = 0; - do - { - if ( loopCount < aRecipient.Length() ) - { - if ( KErrNotFound == KSVPDtmfAllValidChars().Locate( aRecipient[loopCount] ) ) - { - result = EFalse; - loopDo = EFalse; - } - else - { - loopCount++; - } - } - else - { - loopDo = EFalse; - } - } while ( loopDo ); - } - else - { - SVPDEBUG1( "CSVPController::IsValidDtmfRecipientL, Invalid recipient length" ) - result = EFalse; - } - SVPDEBUG2( "CSVPController::IsValidDtmfRecipientL Out, result=%d" , result ) - return result; - } - -// --------------------------------------------------------------------------- -// CSVPController::CheckCallEventToBeSent -// --------------------------------------------------------------------------- -// -void CSVPController::CheckCallEventToBeSent( CSVPSessionBase* aNewSVPSession, - CSVPSessionBase* aOldSVPSession ) const - { - SVPDEBUG1( "CSVPController::CheckCallEventToBeSent In" ) - - if ( aOldSVPSession->IsSecured() != aNewSVPSession->IsSecured() ) - { - // Session secure status changed, need to send proper event - if ( aNewSVPSession->IsSecured() ) - { - SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, unsecure -> secure case" ) - aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPSecureCall ); - } - else - { - SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, secure -> unsecure case" ) - aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPNotSecureCall ); - } - } - else - { - // remoteparty will be updated anyway after attended transfer - SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, remoteparty will be updated after attended transfer" ) - aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPNotifyRemotePartyInfoChange ); - } - SVPDEBUG1( "CSVPController::CheckCallEventToBeSent Out" ) - } - -// --------------------------------------------------------------------------- -// From class MSIPObserver -// CSVPController::IncomingRequest -// --------------------------------------------------------------------------- -// -void CSVPController::IncomingRequest( - TUint32 /*aIapId*/, CSIPServerTransaction* /*aTransaction*/ ) - { - SVPDEBUG1( "CSVPController::IncomingRequest" ) - } - -// --------------------------------------------------------------------------- -// From class MSIPObserver -// CSVPController::TimedOut -// --------------------------------------------------------------------------- -// -void CSVPController::TimedOut( - CSIPServerTransaction& /*aSIPServerTransaction*/ ) - { - SVPDEBUG1( "CSVPController::TimedOut" ) - } - -// --------------------------------------------------------------------------- -// From class MSIPProfileRegistryObserver -// CSVPController::ProfileRegistryErrorOccurred -// --------------------------------------------------------------------------- -// -void CSVPController::ProfileRegistryErrorOccurred( - TUint32 /*aSIPProfileId*/, TInt /*aError*/ ) - { - SVPDEBUG1( "CSVPController::ProfileRegistryErrorOccurred" ) - } - -// --------------------------------------------------------------------------- -// From class MSIPProfileRegistryObserver -// CSVPController::ProfileRegistryEventOccurred -// --------------------------------------------------------------------------- -// -void CSVPController::ProfileRegistryEventOccurred( - TUint32 /*aProfileId*/, TEvent /*aEvent*/ ) - { - SVPDEBUG1( "CSVPController::ProfileRegistryEventOccurred" ) - } -