diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmcccontroller/src/mcccontroller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmcccontroller/src/mcccontroller.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,2585 @@ +/* +* Copyright (c) 2002-2004 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: Controller +* +*/ + + + + +// INCLUDE FILES +#include +#include +#include + +#include "mmccinterface.h" +#include "mmcccodecinformation.h" + +#include "mcccontroller.h" +#include "mcccamerahandler.h" +#include "mcculdlclient.h" +#include "mccuids.hrh" +#include "mccresourcepool.h" +#include "mccresourceitem.h" +#include "mccqoscontroller.h" +#include "mcccontrollerlogs.h" +#include "mccasynclinkcreator.h" +#include "mmcccryptocontext.h" +#include "mccdatasink.h" +#include "mccdatasource.h" +#include "mccrtpdatasink.h" + +const TInt KNumValue2 = 2; + +_LIT( KMccControllerName, "mmcccontroller" ); + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccController::CMccController +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMccController::CMccController() + { + } + +// ----------------------------------------------------------------------------- +// CMccController::~CMccController +// Destructor +// ----------------------------------------------------------------------------- +// +CMccController::~CMccController() + { + __CONTROLLER( "CMccController::~CMccController" ) + + CancelMmfMessage(); + + // delete isessionarray + iSessionArray.ResetAndDestroy(); + iSessionArray.Close(); + + iCreatorArray.ResetAndDestroy(); + iCreatorArray.Close(); + + // delete eventbuffer and contents of it + iEventBuf.ResetAndDestroy(); + iEventBuf.Close(); + + delete iQosController; + + delete iResourcePool; + + if ( iTranscoder ) + { + iTranscoder->UnregisterEventObserver(); + + /* Commented off since causes crash + REComSession::DestroyedImplementation( iTranscoderKey ); + */ + delete iTranscoder; + iTranscoder = NULL; + } + + iDtmfPayloadTypes.Close(); + + #ifdef FTD_ENABLED + iStreamStatsQueue.Close(); + iCodecStatsQueue.Close(); + iJBufferStatsQueue.Close(); + #endif + __CONTROLLER( "CMccController::~CMccController, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::NewL +// Static constructor. +// ----------------------------------------------------------------------------- +// +CMccController* CMccController::NewL() + { + CMccController* self = new ( ELeave ) CMccController; + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CMccController::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMccController::ConstructL() + { + __CONTROLLER( "CMccController::ConstructL" ) + User::LeaveIfError( User::RenameThread( KMccControllerName ) ); + + CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser + = CMMFAudioPlayDeviceCustomCommandParser::NewL( *this ); + CleanupStack::PushL( audPlayDevParser ); + AddCustomCommandParserL( *audPlayDevParser ); + CleanupStack::Pop( audPlayDevParser ); + + CMMFAudioRecordDeviceCustomCommandParser* audRecDevParser + = CMMFAudioRecordDeviceCustomCommandParser::NewL( *this ); + CleanupStack::PushL( audRecDevParser ); + AddCustomCommandParserL( *audRecDevParser ); + CleanupStack::Pop( audRecDevParser ); + + iResourcePool = CMccResourcePool::NewL(); + + iQosController = CMccQosController::NewL( *this, *iResourcePool ); + + __CONTROLLER( "CMccController::ConstructL, creating devsound" ) + + CMMFDevSound* devSound = CMMFDevSound::NewL(); + iMaxVolume = devSound->MaxVolume(); + __CONTROLLER_INT1( "CMccController::ConstructL, max vol:", iMaxVolume ) + iMaxGain = devSound->MaxGain(); + __CONTROLLER_INT1( "CMccController::ConstructL, max gain:", iMaxGain ) + delete devSound; + iVolume = iMaxVolume / KNumValue2; + iGain = iMaxGain / KNumValue2; + + #ifdef FTD_ENABLED + // Message queues are created here and opened by components, + // which will produce messages + User::LeaveIfError( iStreamStatsQueue.CreateGlobal( KMccStreamStats, + KNumOfStreamStatsSlots, EOwnerProcess ) ); + + User::LeaveIfError( iCodecStatsQueue.CreateGlobal( KMccCodecStats, + KNumOfCodecStatsSlots, EOwnerProcess ) ); + + User::LeaveIfError( iJBufferStatsQueue.CreateGlobal( KMccJBufferStats, + KNumOfJBufferStatsSlots, EOwnerProcess ) ); + #endif + __CONTROLLER( "CMccController::ConstructL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetSourceIdL +// ----------------------------------------------------------------------------- +// +void CMccController::GetSourceIdL( TMMFMessage& aMessage ) + { + MDataSource* dataSource = iResourcePool->SourceCandidate(); + __ASSERT_ALWAYS( dataSource, User::Leave( KErrNotFound ) ); + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + pckg().iEndpointID = MCC_ENDPOINT_ID( dataSource ); + aMessage.WriteDataToClientL( pckg ); + } + +// ----------------------------------------------------------------------------- +// CMccController::GetSinkIdL +// ----------------------------------------------------------------------------- +// +void CMccController::GetSinkIdL( TMMFMessage& aMessage ) + { + MDataSink* dataSink = iResourcePool->SinkCandidate(); + __ASSERT_ALWAYS( dataSink, User::Leave( KErrNotFound ) ); + + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + pckg().iEndpointID = MCC_ENDPOINT_ID( dataSink ); + aMessage.WriteDataToClientL( pckg ); + } + +// ----------------------------------------------------------------------------- +// CMccController::CreateSessionL +// Creates new UlDlClient session +// ----------------------------------------------------------------------------- +// +void CMccController::CreateSessionL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CreateSessionL" ) + TMccCreateSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + // Mcc ULDL Client -> NewL + CMccUlDlClient* ulDlClient = + CMccUlDlClient::NewL( this, iResourcePool, iSessionIndex ); + CleanupStack::PushL( ulDlClient ); + iSessionArray.AppendL( ulDlClient ); + CleanupStack::Pop( ulDlClient ); + + __CONTROLLER_INT1( "CMccController::CreateSessionL, session id", iSessionIndex ) + pckg().iSessionID = iSessionIndex; + iSessionIndex++; + + aMessage.WriteDataToClientL( pckg ); + __CONTROLLER( "CMccController::CreateSessionL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::CloseSessionL +// Closes UlDlClient +// ----------------------------------------------------------------------------- +// +void CMccController::CloseSessionL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CloseSessionL" ) + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + + TInt lastIndex = iCreatorArray.Count() - 1; + + for ( TInt i = lastIndex; i >= 0; i-- ) + { + if ( iCreatorArray[i]->GetSessionId() == pckg().iSessionID ) + { + delete iCreatorArray[i]; + iCreatorArray.Remove( i ); + } + } + + delete iSessionArray[session]; + iSessionArray.Remove( session ); + __CONTROLLER( "CMccController::CloseSessionL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::CreateLinkL +// Creates new Ul/Dl Client +// ----------------------------------------------------------------------------- +// +void CMccController::CreateLinkL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CreateLinkL" ) + TMccCreateLinkPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + TInt session = FindSessionL( pckg().iSessionID ); + + CMccAsyncLinkCreator* creator = + CMccAsyncLinkCreator::NewLC( *this, iSessionArray[session] ); + + creator->StartLinkCreationL( aMessage ); + iCreatorArray.AppendL( creator ); + + CleanupStack::Pop( creator ); + } + +// ----------------------------------------------------------------------------- +// CMccController::CloseLinkL +// Closes a Ul/Dl Client +// ----------------------------------------------------------------------------- +// +void CMccController::CloseLinkL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CloseLinkL" ) + TMccGenericMsgBuffer pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->CloseLinkL( pckg().iLinkID ); + // Remove DTMF payload associated with the closed link. + TInt index = iDtmfPayloadTypes.Find( pckg().iLinkID, + TMccKeyValuePair::CompareKey ); + if ( KErrNotFound != index ) + { + __CONTROLLER_INT1( "CMccController::CloseLinkL, REMOVING DTMF PT: ", + iDtmfPayloadTypes[index].Value() ); + + iDtmfPayloadTypes.Remove( index ); + } + + __CONTROLLER( "CMccController::CloseLinkL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::StartStreamL +// Starts stream +// ----------------------------------------------------------------------------- +// +void CMccController::StartStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::StartStreamL" ) + TMccStreamPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iResourcePool->SetEnableRtcpL( pckg().iStreamID, pckg().iEnableRTCP ); + + iSessionArray[session]->PlayL( pckg().iLinkID, pckg().iStreamID, pckg().iEndpointID, + pckg().iStreamPaused, + pckg().iEnableRTCP ); + __CONTROLLER( "CMccController::StartStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::StopStreamL +// Stops stream +// ----------------------------------------------------------------------------- +// +void CMccController::StopStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::StopStreamL" ) + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->StopL( pckg().iLinkID, pckg().iStreamID, + pckg().iEndpointID ); + __CONTROLLER( "CMccController::StopStreamL, exit" ) + } + + +// ----------------------------------------------------------------------------- +// CMccController::StartInactivityTimerL +// Starts inactivity timer for a stream in a given session. +// ----------------------------------------------------------------------------- +// +void CMccController::StartInactivityTimerL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::StartInactivityTimerL" ) + TMccInactivityTimerPckg buffer; + aMessage.ReadData1FromClientL( buffer ); + + TInt session = FindSessionL( buffer().iSessionID ); + iSessionArray[session]->StartInactivityTimerL( buffer().iLinkID, + buffer().iStreamID, + buffer().iTimeoutTime ); + __CONTROLLER( "CMccController::StartInactivityTimerL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::StopInactivityTimerL +// Stops inactivity timer for a stream in a given session. +// ----------------------------------------------------------------------------- +// +void CMccController::StopInactivityTimerL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::StopInactivityTimerL" ) + TMccGenericMsgBuffer buffer; + aMessage.ReadData1FromClientL( buffer ); + + TInt session = FindSessionL( buffer().iSessionID ); + iSessionArray[session]->StopInactivityTimerL( buffer().iLinkID, + buffer().iStreamID ); + __CONTROLLER( "CMccController::StopInactivityTimerL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::RequestEventNotificationL +// Requests Event notification +// ----------------------------------------------------------------------------- +// +void CMccController::RequestEventNotificationL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::RequestEventNotificationL" ) + + CancelMmfMessage(); + + TMccEventPackage pckg; + aMessage.ReadData1FromClientL( pckg ); + + iMessage = new ( ELeave ) TMMFMessage( aMessage ); + + SendEvent(); + + __CONTROLLER( "CMccController::RequestEventNotificationL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SendEvent +// Calls SendEventL() +// ----------------------------------------------------------------------------- +// +void CMccController::SendEvent() + { + __CONTROLLER( "CMccController::SendEvent" ) + TRAPD( err, SendEventL() ); + if ( err ) + { + __CONTROLLER_INT1( "CMccController::SendEventL, leaved with err:", err ) + } + } + +// ----------------------------------------------------------------------------- +// CMccController::SendEventL +// Sends event to clientside +// ----------------------------------------------------------------------------- +// +void CMccController::SendEventL() + { + if ( iMessage && iEventBuf.Count() ) + { + TMccEvent* event = iEventBuf[ 0 ]; + + TMccEventPackage pckg( *event ); + iMessage->WriteDataToClientL( pckg ); + + // 2) Complete the iMessage. + iMessage->Complete( KErrNone ); + delete iMessage; + iMessage = 0; + + iEventBuf.Remove( 0 ); + delete event; + } + } + + +// ----------------------------------------------------------------------------- +// CMccController::AddDataSinkL +// Adds data sink +// ----------------------------------------------------------------------------- +// +void CMccController::AddDataSinkL( MDataSink& aSink ) + { + __CONTROLLER( "CMccController::AddDataSinkL" ) + __CONTROLLER_INT1( "CMccController sink", aSink.DataSinkType().iUid ) + + iResourcePool->ReserveSinkL( &aSink, MCC_ENDPOINT_ID( &aSink ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::AddDataSourceL +// Adds data source +// ----------------------------------------------------------------------------- +// +void CMccController::AddDataSourceL( MDataSource& aSource ) + { + __CONTROLLER( "CMccController::AddDataSourceL" ) + __CONTROLLER_INT1( "CMccController source", aSource.DataSourceType().iUid ) + + iResourcePool->ReserveSourceL( &aSource, MCC_ENDPOINT_ID( &aSource ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::RemoveDataSourceL +// ----------------------------------------------------------------------------- +// +void CMccController::RemoveDataSourceL( MDataSource& aDataSource ) + { + RemoveEndpointL( MCC_ENDPOINT_ID( &aDataSource ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::RemoveDataSinkL +// ----------------------------------------------------------------------------- +// +void CMccController::RemoveDataSinkL( MDataSink& aDataSink ) + { + RemoveEndpointL( MCC_ENDPOINT_ID( &aDataSink ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::ResetL +// Not used +// ----------------------------------------------------------------------------- +// +void CMccController::ResetL() + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::PlayL +// Not used +// ----------------------------------------------------------------------------- +// +void CMccController::PlayL() + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::StopL +// Not used +// ----------------------------------------------------------------------------- +// +void CMccController::StopL() + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::PrimeL +// Not used +// ----------------------------------------------------------------------------- +// +void CMccController::PrimeL() + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::PauseL +// Not used +// ----------------------------------------------------------------------------- +// +void CMccController::PauseL() + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::PositionL +// Not supported +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CMccController::PositionL() const + { + User::Leave( KErrNotSupported ); + // Make CW happy, lint #527 + TTimeIntervalMicroSeconds pos( static_cast( 0 ) ); + return pos; + } + +// ----------------------------------------------------------------------------- +// CMccController::SetPositionL +// Position setting not supported +// ----------------------------------------------------------------------------- +// +void CMccController::SetPositionL( const TTimeIntervalMicroSeconds& /*aPosition*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::DurationL +// Duration not supported +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CMccController::DurationL() const + { + User::Leave( KErrNotSupported ); + // Make CW happy, lint #527 + return TTimeIntervalMicroSeconds( static_cast( 0 ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::SetPrioritySettings +// Sets priority settings +// ----------------------------------------------------------------------------- +// +void CMccController::SetPrioritySettings( const TMMFPrioritySettings& aPrioritySettings ) + { + __CONTROLLER( "CMccController::SetPrioritySettings" ) + iPrioritySettings = aPrioritySettings; + } + +// ----------------------------------------------------------------------------- +// CMccController::SetPriorityL +// Set link priority +// ----------------------------------------------------------------------------- +// +void CMccController::SetPriorityL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetPriorityL" ) + TMccStreamPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TMMFPrioritySettings settings; + settings.iPref = EMdaPriorityPreferenceNone; + settings.iState = EMMFStateIdle; + settings.iPriority = pckg().iPriority; + + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->SetPriorityL( pckg().iLinkID, pckg().iStreamID, + settings ); + __CONTROLLER( "CMccController::SetPriorityL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetNumberOfMetaDataEntriesL +// ----------------------------------------------------------------------------- +// +void CMccController::GetNumberOfMetaDataEntriesL( TInt& /*aNumberOfEntries*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::GetMetaDataEntryL +// ----------------------------------------------------------------------------- +// +CMMFMetaDataEntry* CMccController::GetMetaDataEntryL( TInt /*aIndex*/ ) + { + User::Leave( KErrNotSupported ); + // Make CW happy, lint #527 + return NULL; + } + +// ----------------------------------------------------------------------------- +// CMccController::CreateStreamL +// Creates stream +// ----------------------------------------------------------------------------- +// +void CMccController::CreateStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CreateStreamL" ) + + MDataSource* dataSource = iResourcePool->SourceCandidate(); + MDataSink* dataSink = iResourcePool->SinkCandidate(); + __ASSERT_ALWAYS( dataSource, User::Leave( KErrNotReady ) ); + __ASSERT_ALWAYS( dataSink, User::Leave( KErrNotReady ) ); + + TMccGenericMsgBuffer localBuffer; + aMessage.ReadData1FromClientL( localBuffer ); + + TInt session = FindSessionL( localBuffer().iSessionID ); + + // Read stream creation parameters from message + TMccCreateStreamParamPckg paramPckg; + aMessage.ReadData2FromClientL( paramPckg ); + + TUint32 dataSourceUid = dataSource->DataSourceType().iUid; + + if ( MCC_INTERNAL_ENDPOINT( dataSourceUid ) ) + { + CMccDataSource* mccDataSource = static_cast( dataSource ); + UpdateEndpointVolumeSettings( *mccDataSource ); + } + + TUint32 dataSinkUid = dataSink->DataSinkType().iUid; + + if ( MCC_INTERNAL_ENDPOINT( dataSinkUid ) ) + { + CMccDataSink* mccDataSink = static_cast( dataSink ); + UpdateEndpointVolumeSettings( *mccDataSink ); + } + + localBuffer().iStreamID = iSessionArray[session]->GenerateStreamId(); + + // TBD! IapId has to be fetched from link + + // Standby should be enabled only for audio downlink + TBool isStandBy( paramPckg().iStandByTimer != 0 && + dataSink->DataSinkType() == KUidMmfAudioOutput && + dataSource->DataSourceType() == KMccRtpSourceUid ); + + // TMccGenericMessage's iMessageFunction contains the stream type in the + // case of stream creation, modify stream type if standby timer is enabled + // and allowed (usage rights are checked in resource pool). + TInt streamType = isStandBy ? + KMccAudioDownlinkStandbyStream : paramPckg().iStreamType; + + TMccResourceParams resourceParams( localBuffer().iSessionID, + localBuffer().iLinkID, + localBuffer().iStreamID, + 0, + isStandBy, + streamType ); + + iResourcePool->ReserveResourcesL( resourceParams ); + + iSessionArray[session]->OpenL( localBuffer().iLinkID, + localBuffer().iStreamID, + streamType, + paramPckg().iFourCC, + dataSource, + dataSink, + paramPckg().iPrioritySettings ); + + iSessionArray[session]->SetVolumeL( iVolume ); + + // Need to write the stream ID back to client side + aMessage.WriteDataToClientL( localBuffer ); + + __CONTROLLER( "CMccController::CreateStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::DeleteStreamL +// Deletes stream +// ----------------------------------------------------------------------------- +// +void CMccController::DeleteStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::DeleteStreamL" ) + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->CloseL( pckg().iLinkID, pckg().iStreamID ); + + iResourcePool->FreeResources( pckg().iStreamID ); + + __CONTROLLER( "CMccController::DeleteStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::PrepareStreamL +// Prepares stream +// ----------------------------------------------------------------------------- +// +void CMccController::PrepareStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::PrepareStreamL" ) + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->PrepareL( pckg().iLinkID, pckg().iStreamID, + pckg().iEndpointID ); + __CONTROLLER( "CMccController::PrepareStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::PauseStreamL +// Pauses stream +// ----------------------------------------------------------------------------- +// +void CMccController::PauseStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::PauseStreamL" ) + TMccStreamPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iResourcePool->SetEnableRtcpL( pckg().iStreamID, pckg().iEnableRTCP ); + iSessionArray[session]->PauseL( pckg().iLinkID, pckg().iStreamID, + pckg().iEndpointID, pckg().iEnableRTCP ); + __CONTROLLER( "CMccController::PauseStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::ResumeStreamL +// Resumes stream +// ----------------------------------------------------------------------------- +// +void CMccController::ResumeStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::ResumeStreamL" ) + TMccStreamPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + iResourcePool->SetEnableRtcpL( pckg().iStreamID, pckg().iEnableRTCP ); + iSessionArray[session]->ResumeL( pckg().iLinkID, pckg().iStreamID, + pckg().iEndpointID, pckg().iEnableRTCP ); + __CONTROLLER( "CMccController::ResumeStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::ResumeStreamL +// Resumes stream +// ----------------------------------------------------------------------------- +// +void CMccController::StreamsExistsL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::StreamsExistsL" ) + TMccStreamPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + TBool ret = iSessionArray[session]->StreamsExistsL( pckg().iLinkID ); + if ( !ret ) + { + User::Leave( KErrNotFound ); + } + __CONTROLLER( "CMccController::StreamsExistsL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::CustomCommand +// Controller custom commands +// ----------------------------------------------------------------------------- +// +void CMccController::CustomCommand( TMMFMessage& aMessage ) + { + if( KMccUidInterface != aMessage.Destination().InterfaceId() ) + { + // This message was not intended for us + aMessage.Complete( KErrNotSupported ); + return; + } + else + { + // Interface ID matches ours, lets do the custom command + TRAPD( err, CustomCommandL( aMessage ) ) + + if( KErrNone != err ) + { + // Complete the message as it leaved with error. This will probably + // leave the client. + aMessage.Complete( err ); + } + else + { + // ERequestEventNotification is asynchronous and will be + // completed later when events start pouring in + if( ERequestEventNotification != aMessage.Function() ) + { + aMessage.Complete( err ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CMccController::CustomCommandL +// Controller custom commands +// ----------------------------------------------------------------------------- +// +void CMccController::CustomCommandL( TMMFMessage& aMessage ) + { + switch( aMessage.Function() ) + { + case EMccClose: + break; + + case EMccGetSinkId: + GetSinkIdL( aMessage ); + break; + case EMccGetSourceId: + GetSourceIdL( aMessage ); + break; + + // Session + case EMccCreateSession: + CreateSessionL( aMessage ); + break; + case EMccSetRemoteAddress: + SetRemoteAddressL( aMessage ); + break; + case EMccSetRemoteRtcpAddr: + SetRemoteRtcpAddrL( aMessage ); + break; + case EMccCloseSession: + CloseSessionL( aMessage ); + break; + + // Link + case EMccCreateLink: + CreateLinkL( aMessage ); + break; + case EMccCloseLink: + CloseLinkL( aMessage ); + break; + + // Stream + case EMccCreateStream: + CreateStreamL( aMessage ); + break; + case EMccPrepareStream: + PrepareStreamL( aMessage ); + break; + case EMccStartStream: + StartStreamL( aMessage ); + break; + case EMccPauseStream: + PauseStreamL( aMessage ); + break; + case EMccResumeStream: + ResumeStreamL( aMessage ); + break; + case EMccStopStream: + StopStreamL( aMessage ); + break; + case EMccDeleteStream: + DeleteStreamL( aMessage ); + break; + case EMccStreamSettings: + StreamSettingsL( aMessage ); + break; + case EMccStreamsExists: + StreamsExistsL( aMessage ); + break; + + // Inactivity Timer + case EMccInactivityTimerStart: + StartInactivityTimerL( aMessage ); + break; + case EMccInactivityTimerStop: + StopInactivityTimerL( aMessage ); + break; + + // RTCP reports and non-RTCP data + case EMccSendRtcpRR: + SendRTCPReceiverReportL( aMessage ); + break; + case EMccSendRtcpSR: + SendRTCPSenderReportL( aMessage ); + break; + case EMccSendRtcpData: + SendRTCPDataL( aMessage ); + break; + + // Codec + case EMccGetSupportedCodecs: + GetSupportedCodecsL( aMessage ); + break; + case EMccGetCodec: + GetCodecL( aMessage ); + break; + case EMccGetFmtpAttr: + GetFmtpAttrL( aMessage ); + break; + case EMccSetCodec: + SetCodecL( aMessage ); + break; + case EMccGetSupportedBitrates: + GetSupportedBitratesL( aMessage ); + break; + + // SSRC + case EMccGetSSRC: + GetSSRCL( aMessage ); + break; + case EMccSetAudioPriority: + SetPriorityL( aMessage ); + break; + + // Camera + case EMccEnableViewFinder: + EnableViewFinderL( aMessage ); + break; + case EMccDisableViewFinder: + DisableViewFinderL( aMessage ); + break; + case EMccGetViewFinderSettings: + ViewFinderSettingsL( aMessage ); + break; + case EMccGetCamInfo: + GetCamInfoL( aMessage ); + break; + case EMccGetNumOfCams: + GetNumOfCamsL( aMessage ); + break; + case EMccSetCamValue1: + SetCamValue1L( aMessage ); + break; + case EMccGetCamValue1: + GetCamValue1L( aMessage ); + break; + case EMccSetCamValue2: + SetCamValue2L( aMessage ); + break; + case EMccGetCamValue2: + GetCamValue2L( aMessage ); + break; + + // Audio routing + case EMccSetAudioRoute: + SetAudioRouteL( aMessage ); + break; + case EMccGetAudioRoute: + GetAudioRouteL( aMessage ); + break; + + // Endpoint handling + case EMccReuse: + ReuseL( aMessage ); + break; + case EMccGetReferenceCount: + ReferenceCountL( aMessage ); + break; + case EMccSetEndpointParameter: + SetEndpointParameterL( aMessage ); + break; + case EMccGetEndpointParameter: + GetEndpointParameterL( aMessage ); + break; + case EMccUpdateDataSink: + case EMccUpdateDataSource: + UpdateEndpointL( aMessage ); + break; + + // transcode file + case EMccTranscodeFile: + TranscodeFileL( aMessage ); + break; + case EMccCancelTranscodeFile: + CancelTranscodeFileL( aMessage ); + break; + + // Generic + case ERequestEventNotification: + RequestEventNotificationL( aMessage ); + break; + case EMccSendMediaSignal: + SendMediaSignalL( aMessage ); + break; + case EMccCancel: + CancelMmfMessage(); + break; + + // Secure + case EMccBindContextIntoStream: + BindContextIntoStreamL( aMessage ); + break; + case EMccRemoveContext: + RemoveContextL( aMessage ); + break; + default: + User::Leave( KErrNotSupported ); + break; + } // end of switch + } + +// ----------------------------------------------------------------------------- +// CMccController::GetSupportedCodecsL +// Puts supported codecs into fourcc array +// ----------------------------------------------------------------------------- +// +void CMccController::GetSupportedCodecsL( TMMFMessage& aMessage ) const + { + __CONTROLLER( "CMccController::GetSupportedCodecsL" ) + + TMccSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + TFixedArray& codecs = pckg().iFourCCArray; + TInt index( 0 ); + + // Audio codecs + CMMFDevSound* devSound = CMMFDevSound::NewL(); + CleanupStack::PushL( devSound ); + + TMMFPrioritySettings dummy; + RArray< TFourCC > outCodecs; + devSound->GetSupportedOutputDataTypesL( outCodecs, dummy ); + CleanupClosePushL( outCodecs ); + + RArray< TFourCC > inCodecs; + devSound->GetSupportedInputDataTypesL( inCodecs, dummy ); + CleanupClosePushL( inCodecs ); + + // Support dynamically checked from CMMFDevSound in HW + AddCodec( KMccFourCCIdAMRWB, outCodecs, inCodecs, codecs, index++ ); + AddCodec( KMccFourCCIdAMRNB, outCodecs, inCodecs, codecs, index++ ); + AddCodec( KMccFourCCIdG711, outCodecs, inCodecs, codecs, index++ ); + AddCodec( KMccFourCCIdILBC, outCodecs, inCodecs, codecs, index++ ); + AddCodec( KMccFourCCIdG729, outCodecs, inCodecs, codecs, index++ ); + // Not in CMMFDevSound's list + codecs[ index++ ] = TFourCC( KMccFourCCIdDTMF ); + codecs[ index++ ] = TFourCC( KMccFourCCIdRed ); + codecs[ index++ ] = TFourCC( KMccFourCCIdCN ); + + CleanupStack::PopAndDestroy( &inCodecs ); + CleanupStack::PopAndDestroy( &outCodecs ); + CleanupStack::PopAndDestroy( devSound ); + + // Video codecs + codecs[ index++ ] = TFourCC( KMccFourCCIdAVC ); + codecs[ index ] = TFourCC( KMccFourCCIdH263 ); + + aMessage.WriteDataToClientL( pckg ); + + __CONTROLLER( "CMccController::GetSupportedCodecsL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetCodecL +// Gets current codec +// ----------------------------------------------------------------------------- +// +void CMccController::GetCodecL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetCodecL" ) + TMccGenericMsgBuffer pckg; + TMccCodecInfo codecInfo; + aMessage.ReadData1FromClientL( pckg ); + + if( pckg().iSessionID == 0 && pckg().iLinkID == 0) + { + TUid targetUid; + targetUid.iUid = (TUint) pckg().iStreamID; + CMccUlDlClient::GetCodecDefaultsL( targetUid, pckg().iParam1, codecInfo); + } + else + { + TInt session = FindSessionL( pckg().iSessionID ); + iSessionArray[session]->GetCodecL( pckg().iLinkID, + pckg().iStreamID, + codecInfo ); + } + TMccCodecInfoBuffer writeBuffer( codecInfo ); + aMessage.WriteDataToClientL( writeBuffer ); + __CONTROLLER( "CMccController::GetCodecL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetFmtpAttrL +// Gets current codec +// ----------------------------------------------------------------------------- +// +void CMccController::GetFmtpAttrL( TMMFMessage& /*aMessage*/ ) + { + __CONTROLLER( "CMccController::GetFmtpAttrL" ) + User::Leave( KErrNotSupported ); + __CONTROLLER( "CMccController::GetFmtpAttrL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetCodecL +// Sets codec. +// ----------------------------------------------------------------------------- +// +void CMccController::SetCodecL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetCodecL" ) + TMccCodecInfoBuffer readBuffer; + aMessage.ReadData1FromClientL( readBuffer ); + + TInt session = FindSessionL( readBuffer().iSessionID ); + iSessionArray[session]->SetCodecInformationL( readBuffer().iLinkID, + readBuffer().iStreamID, + readBuffer(), + KNullDesC8 ); + aMessage.WriteDataToClientL( readBuffer ); + + if ( 0 == readBuffer().iSdpName.Compare( KTelephoneEvent ) ) + { + TInt index = iDtmfPayloadTypes.Find( readBuffer().iLinkID, + TMccKeyValuePair::CompareKey ); + if ( KErrNotFound != index ) + { + // Remove DTMF payload type for audio muting functionality + __CONTROLLER_INT1( "CMccController::SetCodecL, REMOVE INDEX:", + index ); + iDtmfPayloadTypes.Remove( index ); + } + // Save DTMF payload type for audio muting functionality during + // DTMF sending. + __CONTROLLER_INT1( "CMccController::SetCodecL, SAVING DTMF PT:", + readBuffer().iPayloadType ); + TMccKeyValuePair< TUint32, TUint8 > keyValuePair( + readBuffer().iLinkID, readBuffer().iPayloadType ); + iDtmfPayloadTypes.AppendL( keyValuePair ); + } + + __CONTROLLER( "CMccController::SetCodecL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetSupportedBitratesL +// Gets the supported bitrates from the codec of the specified stream +// ----------------------------------------------------------------------------- +// +void CMccController::GetSupportedBitratesL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetSupportedBitratesL" ) + TMccGenericMsgBuffer pckg; + aMessage.ReadData1FromClientL( pckg ); + TInt session = FindSessionL( pckg().iSessionID ); + + RArray bitrateArray; + iSessionArray[session]->GetSupportedBitratesL( pckg().iLinkID, + pckg().iStreamID, + bitrateArray ); + + // Move the bitrates to a package descriptor + TMccBitrates bitrates; + for ( TInt i = 0; ( i < bitrateArray.Count() ) && i < KMaxBitrates; i++ ) + { + bitrates.iBitrates[i] = bitrateArray[i]; + } + bitrateArray.Close(); + + TMccBitratesPckg writeBuffer( bitrates ); + aMessage.WriteDataToClientL( writeBuffer ); + __CONTROLLER( "CMccController::GetSupportedBitratesL, exit" ) + } + + +// ----------------------------------------------------------------------------- +// CMccController::GetSSRCL +// Gets the syncronization source from the specified stream +// ----------------------------------------------------------------------------- +// +void CMccController::GetSSRCL ( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetSSRCL" ) + TMccGenericMsgBuffer pckg; + aMessage.ReadData1FromClientL( pckg ); + TInt session = FindSessionL( pckg().iSessionID ); + + TMccSSRC ssrc; + iSessionArray[session]->GetSSRCL( pckg().iLinkID, + pckg().iStreamID, + ssrc.iSSRC ); + + TMccSSRCPckg ssrcPckg(ssrc); + aMessage.WriteDataToClientL( ssrcPckg ); + __CONTROLLER( "CMccController::GetSSRCL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetRemoteAddressL +// Sets remote address +// ----------------------------------------------------------------------------- +// +void CMccController::SetRemoteAddressL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetRemoteAddressL" ) + TMccAddressPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + + iSessionArray[session]->SetRemoteAddressL( pckg().iAddress, + pckg().iLinkID ); + __CONTROLLER( "CMccController::SetRemoteAddressL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetRemoteRtcpAddrL +// Sets remote address +// ----------------------------------------------------------------------------- +// +void CMccController::SetRemoteRtcpAddrL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetRemoteRtcpAddrL" ) + TMccAddressPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + TInt session = FindSessionL( pckg().iSessionID ); + + iSessionArray[session]->SetRemoteRtcpAddrL( pckg().iAddress, + pckg().iLinkID ); + __CONTROLLER( "CMccController::SetRemoteAddrL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SendMccEventToClient +// Enqueues MccEvent to eventbuffer and sends it to client +// ----------------------------------------------------------------------------- +// +TInt CMccController::SendMccEventToClient( TMccEvent& aEvent ) + { + __CONTROLLER( "CMccController::SendMccEventToClient" ) + __CONTROLLER_INT1( "CMccController event category", aEvent.iEventCategory ) + __CONTROLLER_INT1( "CMccController event type", aEvent.iEventType ) + + TInt err( KErrNone ); + TBool discardEvent( EFalse ); + TBool streamControl( EFalse ); + TMccEvent* additionalControlEvent( NULL ); + + // Show event to the QosController + discardEvent = iQosController->EventReceived( aEvent ); + + if ( !discardEvent ) + { + if ( aEvent.iEventCategory == KMccEventCategoryStream ) + { + if ( aEvent.iEventType == KMccStreamMMFEvent && + aEvent.iErrorCode == KErrDied ) + { + // Resource not available, disable the endpoint + + __CONTROLLER( "CMccController::SendMccEventToClient, \ +MMF resource not available" ) + + discardEvent = ETrue; + streamControl = ETrue; + + // Modify event to be "resource not available" event + aEvent.iEventCategory = KMccEventCategoryStream; + aEvent.iEventType = KMccResourceNotAvailable; + StoreAndSendEvent( aEvent ); + + // Modify event to be "stream control" event + aEvent.iEventType = KMccStreamPaused; + } + else + { + TBool effectiveStandby( EFalse ); + err = iResourcePool->EventReceived( aEvent, + discardEvent, + effectiveStandby, + &additionalControlEvent ); + streamControl = effectiveStandby; + } + } + else if ( aEvent.iEventCategory == KMccEventCategoryStreamControl ) + { + // Filter stream control event over here + discardEvent = ETrue; + streamControl = ETrue; + } + else if ( KMccEventCategoryDtmf == aEvent.iEventCategory && + KMccDtmfControl == aEvent.iEventType ) + { + // Unmute RTP sink regarding audio payloads when DTMF sending is + // stopped. Audio can be sent between key presses. + const TMccDtmfEventData& dtmfEvent = + (*reinterpret_cast( + &aEvent.iEventData ) ) (); + + if ( KMccDtmfManualStop == dtmfEvent.iDtmfEventType || + KMccDtmfManualAbort == dtmfEvent.iDtmfEventType || + KMccDtmfSequenceStop == dtmfEvent.iDtmfEventType || + KMccDtmfSequenceAbort == dtmfEvent.iDtmfEventType || + KMccDtmfStopInDtmfString == dtmfEvent.iDtmfEventType ) + { + MDataSource* dataSource; + MDataSink* dataSink; + err = iResourcePool->FindResource( aEvent.iLinkId, + aEvent.iEndpointId, KMccRtpSinkUid, &dataSource, + &dataSink ); + + if ( KErrNone == err ) + { + CMccRtpDataSink* rtpSink + = static_cast( dataSink ); + if ( rtpSink ) + { + rtpSink->Mute( EFalse, KPayloadTypeUndefined ); + } + } + else + { + __CONTROLLER_INT1( + "CMccController::SendMccEventToClient DTMF ERR", err ) + } + } + } + else + { + } + } + + if ( !err && !discardEvent ) + { + err = StoreAndSendEvent( aEvent ); + } + + if ( !err && streamControl ) + { + TRAP( err, StreamActionL( aEvent, additionalControlEvent ) ); + if ( err ) + { + // Modify event to contain error info + aEvent.iEventCategory = KMccEventCategoryStream; + aEvent.iEventType = KMccStreamError; + aEvent.iEventData.Zero(); + aEvent.iErrorCode = err; + StoreAndSendEvent( aEvent ); + } + } + + delete additionalControlEvent; + + return err; + } + +// ----------------------------------------------------------------------------- +// CMccController::PauseByEndPointIdL +// ----------------------------------------------------------------------------- +// +void CMccController::PauseByEndPointIdL( + const TMccEvent& aEvent, + TUint32 aEndPointId ) + { + TInt session = FindSessionL( aEvent.iSessionId ); + + iSessionArray[session]->PauseL( + aEvent.iLinkId, + aEvent.iStreamId, + aEndPointId, + iResourcePool->EnableRtcp( aEvent.iStreamId ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::ResumeByEndPointIdL +// ----------------------------------------------------------------------------- +// +void CMccController::ResumeByEndPointIdL( + const TMccEvent& aEvent, + TUint32 aEndPointId ) + { + TInt session = FindSessionL( aEvent.iSessionId ); + + iSessionArray[session]->ResumeL( + aEvent.iLinkId, + aEvent.iStreamId, + aEndPointId, + iResourcePool->EnableRtcp( aEvent.iStreamId ) ); + } + +// ----------------------------------------------------------------------------- +// CMccController::UpdateEndpointVolumeSettings +// ----------------------------------------------------------------------------- +// +TInt CMccController::UpdateEndpointVolumeSettings( MMccSourceSink& aEndpoint ) + { + // Some endpoints do not support volume setting, that's ok + TRAPD( err, aEndpoint.SetParameterL( KMccSpeakerMaxVolume, + TPckgBuf( iMaxVolume ) ) ); + if ( !err ) + { + TRAP( err, aEndpoint.SetParameterL( KMccSpeakerVolume, + TPckgBuf( iVolume ) ) ); + } + return err; + } + +// ----------------------------------------------------------------------------- +// CMccController::StateChange +// ----------------------------------------------------------------------------- +// +void CMccController::StateChange( TInt /*aState*/, TUint32 /*aLinkId*/ ) + { + __CONTROLLER( "CMccController::SendMccEventToClient ignoring" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::ErrorOccured +// ----------------------------------------------------------------------------- +// +void CMccController::ErrorOccured( + TInt aError, + TUint32 aSessionId, + TUint32 aLinkId, + TUint32 aStreamId, + TUint32 aEndpointId ) + { + __CONTROLLER_INT1( "CMccController::ErrorOccured", aError ) + __CONTROLLER_INT1( "CMccController sessionid", aSessionId ) + __CONTROLLER_INT1( "CMccController linkid", aLinkId ) + __CONTROLLER_INT1( "CMccController streamId", aStreamId ) + __CONTROLLER_INT1( "CMccController endpointId", aEndpointId ) + + if ( KErrNone != aError ) + { + TMccEvent event( aSessionId, aLinkId, aStreamId, aEndpointId, + KMccEventCategoryStream, KMccStreamError, aError, KNullDesC8 ); + + SendMccEventToClient( event ); + } + + __CONTROLLER( "CMccController::ErrorOccured, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::StreamSettingsL +// Sets stream settings +// ----------------------------------------------------------------------------- +// +void CMccController::StreamSettingsL( TMMFMessage& aMessage ) + { + aMessage.ReadData1FromClientL( iStreamPckg ); + // Check the session ID already at this stage to avoid a panic from the MMF + TInt dummy = FindSessionL( iStreamPckg().iSessionID ); + dummy = dummy; + } + +// ----------------------------------------------------------------------------- +// CMccController::SendRTCPReceiverReport +// Sends a RTCP receiver report +// ----------------------------------------------------------------------------- +// +void CMccController::SendRTCPReceiverReportL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SendRTCPReceiverReportL" ) + TMccGenericMsgBuffer buffer; + aMessage.ReadData1FromClientL( buffer ); + + TInt session = FindSessionL( buffer().iSessionID ); + iSessionArray[session]->SendRTCPReceiverReportL( buffer().iLinkID, + buffer().iStreamID ); + __CONTROLLER( "CMccController::SendRTCPReceiverReportL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SendRTCPSenderReport +// Sends a RTCP receiver report +// ----------------------------------------------------------------------------- +// +void CMccController::SendRTCPSenderReportL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SendRTCPSenderReportL" ) + TMccGenericMsgBuffer buffer; + aMessage.ReadData1FromClientL( buffer ); + TInt session = FindSessionL( buffer().iSessionID ); + iSessionArray[session]->SendRTCPSenderReportL( buffer().iLinkID, + buffer().iStreamID ); + __CONTROLLER( "CMccController::SendRTCPSenderReportL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SendRTCPDataL +// Sends non-RTCP data +// ----------------------------------------------------------------------------- +// +void CMccController::SendRTCPDataL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SendRTCPDataL" ) + TMccGenericMsgBuffer buffer; + aMessage.ReadData1FromClientL( buffer ); + TInt session = FindSessionL( buffer().iSessionID ); + + // Copy the data locally + HBufC8* dataBuf( NULL ); + dataBuf = HBufC8::NewLC( aMessage.SizeOfData2FromClient() ); + TPtr8 ptr( dataBuf->Des() ); + aMessage.ReadData2FromClientL( ptr ); + iSessionArray[session]->SendRTCPDataL( buffer().iLinkID, + buffer().iStreamID, + *dataBuf ); + CleanupStack::PopAndDestroy( dataBuf ); + __CONTROLLER( "CMccController::SendRTCPDataL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdGetVolumeL +// Gets downlink volume. +// ----------------------------------------------------------------------------- +// +void CMccController::MapdGetVolumeL( TInt& aVolume ) + { + aVolume = iVolume; + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdGetMaxVolumeL +// Gets downlink stream Max volume. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MapdGetMaxVolumeL( TInt& aMaxVolume ) + { + aMaxVolume = iMaxVolume; + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdSetVolumeL +// Sets volume to all sessions +// ----------------------------------------------------------------------------- +// +void CMccController::MapdSetVolumeL( TInt aVolume ) + { + if ( aVolume >= 0 && aVolume <= iMaxVolume ) + { + iVolume = aVolume; + + for ( TInt i=0; i < iSessionArray.Count(); i++ ) + { + iSessionArray[i]->SetVolumeL( aVolume ); + } + } + else + { + User::Leave( KErrArgument ); + } + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdGetBalanceL +// Gets play balance. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MapdGetBalanceL( TInt& aBalance ) + { + TInt left( 0 ); + TInt right( 0 ); + TInt session = FindSessionL( iStreamPckg().iSessionID ); + iSessionArray[session]->GetPlayBalanceL( iStreamPckg().iLinkID, + iStreamPckg().iStreamID, + left, right ); + + // The right + left balances are <= 100 (%) + // Here, the balances are converted to one value between -100 and 100 (L-R) + aBalance = ( KNumValue2 * right ) - KMaxBalance; + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdSetBalanceL +// Sets play balance. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MapdSetBalanceL( TInt aBalance ) + { + if( aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight ) + { + User::Leave( KErrArgument ); + } + + // The right + left balances should be <= 100 (%) + TInt right = ( KMaxBalance + aBalance ) / KNumValue2; + TInt left = KMaxBalance - right; + + TInt session = FindSessionL( iStreamPckg().iSessionID ); + iSessionArray[session]->SetPlayBalanceL( iStreamPckg().iLinkID, + iStreamPckg().iStreamID, + left, right ); + } + +// ----------------------------------------------------------------------------- +// CMccController::MapdSetVolumeRampL +// ----------------------------------------------------------------------------- +// +void CMccController::MapdSetVolumeRampL( const TTimeIntervalMicroSeconds& /*aRampDuration*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccController::MardSetGainL +// Sets uplink gain to all sessions. +// ----------------------------------------------------------------------------- +// +void CMccController::MardSetGainL( TInt aGain ) + { + iGain = aGain; + + for ( TInt i=0; i < iSessionArray.Count(); i++ ) + { + iSessionArray[i]->SetGainL(aGain); + } + } + +// ----------------------------------------------------------------------------- +// CMccController::MardGetMaxGainL +// Gets uplink stream Max gain. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MardGetMaxGainL( TInt& aMaxGain ) + { + aMaxGain = iMaxGain; + } + +// ----------------------------------------------------------------------------- +// CMccController::MardGetGainL +// Gets uplink gain. +// ----------------------------------------------------------------------------- +// +void CMccController::MardGetGainL( TInt& aGain ) + { + aGain = iGain; + } + +// ----------------------------------------------------------------------------- +// CMccController::MardSetBalanceL +// Sets record balance. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MardSetBalanceL( TInt aRBalance ) + { + if( aRBalance < KMMFBalanceMaxLeft || aRBalance > KMMFBalanceMaxRight ) + { + User::Leave( KErrArgument ); + } + + // The right + left balances should be <= 100% + TInt right = ( KMaxBalance + aRBalance ) / KNumValue2; + TInt left = KMaxBalance - right; + + TInt session = FindSessionL( iStreamPckg().iSessionID ); + iSessionArray[session]->SetRecordBalanceL( iStreamPckg().iLinkID, + iStreamPckg().iStreamID, + left, right ); + } + +// ----------------------------------------------------------------------------- +// CMccController::MardGetBalanceL +// Gets record balance. Uses stream settings from iStreamPckg. +// ----------------------------------------------------------------------------- +// +void CMccController::MardGetBalanceL( TInt& aRecBalance ) + { + TInt left( 0 ); + TInt right( 0 ); + TInt session = FindSessionL( iStreamPckg().iSessionID ); + iSessionArray[session]->GetRecordBalanceL( iStreamPckg().iLinkID, + iStreamPckg().iStreamID, left, right ); + + // The right + left balances are <= 100 (%) + // Here, the balances are converted to one value between -100 and 100 (L-R) + aRecBalance = ( KNumValue2 * right ) - KMaxBalance; + } + +// ----------------------------------------------------------------------------- +// CMccController::FindSessionL +// Finds sessionindex for sessionarray +// ----------------------------------------------------------------------------- +// +TInt CMccController::FindSessionL( TUint32 aSessionID ) + { + __CONTROLLER_INT1( "CMccController::FindSessionL, session id", aSessionID ) + TInt sessionCount = iSessionArray.Count(); + TInt err = KErrNotFound; + TInt sessionID = 0; + + for ( TInt i = 0; i < sessionCount; i++ ) + { + if ( iSessionArray[i]->GetSessionId() == aSessionID ) + { + sessionID = i; + err = KErrNone; + } + } + + if ( err == KErrNotFound ) + { + User::Leave( err ); + } + + return sessionID; + } + +// ----------------------------------------------------------------------------- +// CMccController::SendMediaSignalL +// Sends media signal to stream +// ----------------------------------------------------------------------------- +// +void CMccController::SendMediaSignalL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SendMediaSignalL" ) + + // Get the media event package, find session and send the event. + TMccEventPackage eventPkg; + aMessage.ReadData1FromClientL( eventPkg ); + + TInt session = FindSessionL( eventPkg().iSessionId ); + + if ( KMccEventCategoryDtmf == eventPkg().iEventCategory && + KMccDtmfControl == eventPkg().iEventType ) + { + const TMccDtmfEventData& dtmfEvent = + (*reinterpret_cast( + &eventPkg().iEventData ) ) (); + + if ( KMccDtmfSigStartTone == dtmfEvent.iDtmfEventType || + KMccDtmfSigSendString == dtmfEvent.iDtmfEventType || + KMccDtmfSigContinueSending == dtmfEvent.iDtmfEventType ) + { + // Simultaneous audio and outband DTMF sending confuses some + // servers and thus audio sending must be disabled until DTMF + // sending is completed. + + // DTMF and audio MUST share same SSRC. RTP-sink corresponds SSRC, + // so DTMF and audio use same RTP sink. Video streams MUST have + // own RTP-sink instance because of different data source. + MDataSource* dataSource; + MDataSink* dataSink; + iResourcePool->FindResource( eventPkg().iLinkId, + eventPkg().iEndpointId, KMccRtpSinkUid, &dataSource, + &dataSink ); + CMccRtpDataSink* rtpSink + = static_cast( dataSink ); + + // Find DTMF payload type used with the RTP-session(MCC link) and + // mute other payloads + TInt index = iDtmfPayloadTypes.Find( eventPkg().iLinkId, + TMccKeyValuePair::CompareKey ); + if ( KErrNotFound != index && NULL != rtpSink ) + { + rtpSink->Mute( ETrue, iDtmfPayloadTypes[index].Value() ); + } + else + { + // If DTMF payload type finding fails, try one's best and send + // DTMF simultaneously with audio. + __CONTROLLER_INT1( "CMccController::SendMediaSignalL, ERR", + index ) + } + } + } + + iSessionArray[session]->SendMediaSignalL( eventPkg() ); + __CONTROLLER( "CMccController::SendMediaSignalL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::EnableViewFinderL +// ----------------------------------------------------------------------------- +// +void CMccController::EnableViewFinderL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::EnableViewFinderL" ) + + TMccVideoSinkSettingBuf localBuffer; + aMessage.ReadData1FromClientL( localBuffer ); + iResourcePool->EnableViewFinderL( localBuffer() ); + + __CONTROLLER( "CMccController::EnableViewFinderL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::DisableViewFinderL +// ----------------------------------------------------------------------------- +// +void CMccController::DisableViewFinderL( TMMFMessage& /*aMessage*/ ) + { + __CONTROLLER( "CMccController::DisableViewFinderL" ) + + iResourcePool->DisableViewFinderL(); + + __CONTROLLER( "CMccController::DisableViewFinderL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::ViewFinderSettingsL +// ----------------------------------------------------------------------------- +// +void CMccController::ViewFinderSettingsL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::ViewFinderSettingsL" ) + + TMccGenericMsgBuffer packBuf; + aMessage.ReadData1FromClientL( packBuf ); + TMccVideoSinkSettingBuf localBuffer; + aMessage.ReadData2FromClientL( localBuffer ); + iResourcePool->CameraHandlerL().GetViewFinderSettingsL( localBuffer() ); + aMessage.WriteDataToClientL( localBuffer ); + + __CONTROLLER( "CMccController::ViewFinderSettingsL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetCamInfoL +// Puts supported codecs into fourcc array +// ----------------------------------------------------------------------------- +// +void CMccController::GetCamInfoL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetCamInfoL" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + TCameraInfo camInfo; + TPckgBuf camBuffer( camInfo ); + + CMccCameraHandler* cameraHandler = 0; + + // Disabling a PC-lint warning about passing an expression to TRAP_IGNORE macro + /*lint -e665*/ + TRAP_IGNORE( cameraHandler = &iResourcePool->CameraHandlerL( EFalse, package().iParam2 ) ) + /*lint +e665*/ + + if ( !cameraHandler ) + { + // Create temporary camera handler + cameraHandler = iResourcePool->CreateNewCameraHandlerL( package().iParam2 ); + CleanupStack::PushL( cameraHandler ); + cameraHandler->GetCamInfoL( camBuffer(), ETrue ); + CleanupStack::PopAndDestroy( cameraHandler ); + } + else + { + cameraHandler->GetCamInfoL( camBuffer(), ETrue ); + } + + aMessage.WriteDataToClientL( camBuffer ); + __CONTROLLER( "CMccController::GetCamInfoL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetNumOfCamsL +// ----------------------------------------------------------------------------- +// +void CMccController::GetNumOfCamsL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetNumOfCamsL" ) + TPckgBuf buffer; + aMessage.ReadData1FromClientL( buffer ); + + buffer() = CMccCameraHandler::GetNumOfCamerasL(); + + aMessage.WriteDataToClientL( buffer ); + __CONTROLLER( "CMccController::GetNumOfCamsL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetCamValue1L +// ----------------------------------------------------------------------------- +// +void CMccController::GetCamValue1L( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetCamValue1L" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + iResourcePool->CameraHandlerL().GetValueL( package().iMessageFunction, + package().iParam4 ); + + aMessage.WriteDataToClientL( package ); + __CONTROLLER( "CMccController::GetCamValue1L, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetCamValue1L +// ----------------------------------------------------------------------------- +// +void CMccController::SetCamValue1L( TMMFMessage& aMessage ) + { + + __CONTROLLER( "CMccController::SetCamValue1L" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + iResourcePool->CameraHandlerL().SetValueL( package().iMessageFunction, + package().iParam4 ); + + __CONTROLLER( "CMccController::SetCamValue1L, exit" ) + + } + +// ----------------------------------------------------------------------------- +// CMccController::GetCamValue2L +// ----------------------------------------------------------------------------- +// +void CMccController::GetCamValue2L( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetCamValue2L" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + iResourcePool->CameraHandlerL().GetValueL( package().iMessageFunction, + package().iParam3 ); + + aMessage.WriteDataToClientL( package ); + __CONTROLLER( "CMccController::GetCamValue2L, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetCamValue2L +// ----------------------------------------------------------------------------- +// +void CMccController::SetCamValue2L( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetCamValue2L" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + iResourcePool->CameraHandlerL().SetValueL( package().iMessageFunction, + package().iParam3 ); + __CONTROLLER( "CMccController::SetCamValue2L, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetAudioRouteL +// ----------------------------------------------------------------------------- +// +void CMccController::SetAudioRouteL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetAudioRouteL" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + TInt session = FindSessionL( package().iSessionID ); + + iSessionArray[ session ]->SetAudioRouteL( package().iLinkID, + package().iStreamID, + package().iParam2 ); + + __CONTROLLER( "CMccController::SetAudioRouteL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetAudioRouteL +// ----------------------------------------------------------------------------- +// +void CMccController::GetAudioRouteL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetAudioRouteL" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + TInt session = FindSessionL( package().iSessionID ); + + iSessionArray[ session ]->GetAudioRouteL( package().iLinkID, + package().iStreamID, + package().iParam2 ); + + aMessage.WriteDataToClientL( package ); + __CONTROLLER( "CMccController::GetAudioRouteL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::SetEndpointParameterL +// ----------------------------------------------------------------------------- +// +void CMccController::SetEndpointParameterL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::SetEndpointParameterL" ) + + __ASSERT_ALWAYS( iResourcePool, User::Leave( KErrNotReady ) ); + + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + MDataSource* source = 0; + MDataSink* sink = 0; + TInt err = iResourcePool->FindResource( 0, + package().iEndpointID, + KNullUid, + &source, + &sink ); + + switch( package().iParam2 ) + { + case KMccFileInfo: + case KMccFileName: + case KMccFileDuration: + case KMccFileVideoFrameRate: + case KMccFileVideoBitRate: + case KMccFileVideoFrameSize: + case KMccFileAudioBitRate: + case KMccFilePosition: + case KMccFileAudioFourCC: + case KMccFileVideoFourCC: + { + __CONTROLLER( "CMccController::SetEndpointParameterL, file" ) + + User::LeaveIfError( err ); + __ASSERT_ALWAYS( source, User::Leave( KErrNotFound ) ); + CMccDataSource* dataSource = static_cast( source ); + TMccFileSourceSettingBuf fileSetting; + aMessage.ReadData2FromClientL( fileSetting ); + dataSource->SetParameterL( package().iParam2, fileSetting ); + break; + } + case KMccFileFastForward: + { + __CONTROLLER( "CMccController::SetEndpointParameterL, file" ) + + User::LeaveIfError( err ); + __ASSERT_ALWAYS( source, User::Leave( KErrNotFound ) ); + CMccDataSource* dataSource = static_cast( source ); + TPckgBuf fastforwardSettingPak; + aMessage.ReadData2FromClientL( fastforwardSettingPak ); + dataSource->SetParameterL( package().iParam2, fastforwardSettingPak ); + break; + } + case KMccDisplayLocalVideo: + { + __CONTROLLER( "CMccController::SetEndpointParameterL, display" ) + + User::LeaveIfError( err ); + __ASSERT_ALWAYS( sink, User::Leave( KErrNotFound ) ); + CMccDataSink* dataSink = static_cast( sink ); + TMccVideoSinkSettingBuf displaySetting; + aMessage.ReadData2FromClientL( displaySetting ); + dataSink->SetParameterL( package().iParam2, displaySetting ); + break; + } + case KMccRtpCName: + { + __CONTROLLER( "CMccController::SetEndpointParameterL, cname" ) + + // Can be set even if endpoint is not yet there + HBufC8* cname = HBufC8::NewLC( aMessage.SizeOfData2FromClient() ); + TPtr8 ptrCName( cname->Des() ); + aMessage.ReadData2FromClientL( ptrCName ); + TInt session = FindSessionL( package().iSessionID ); + iSessionArray[ session ]->SetParameterL( package().iParam2, + package().iLinkID, + package().iStreamID, + package().iEndpointID, + ptrCName ); + CleanupStack::PopAndDestroy( cname ); + break; + } + default: + { + User::Leave( KErrArgument ); + break; + } + } + + __CONTROLLER( "CMccController::SetEndpointParameterL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::GetEndpointParameterL +// ----------------------------------------------------------------------------- +// +void CMccController::GetEndpointParameterL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::GetEndpointParameterL" ) + + __ASSERT_ALWAYS( iResourcePool, User::Leave( KErrNotReady ) ); + + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + MDataSource* source = 0; + MDataSink* sink = 0; + iResourcePool->FindResource( 0, + package().iEndpointID, + KNullUid, + &source, + &sink ); + switch( package().iParam2 ) + { + case KMccFileInfo: + case KMccFileName: + case KMccFileDuration: + case KMccFileVideoFrameRate: + case KMccFileVideoBitRate: + case KMccFileVideoFrameSize: + case KMccFileAudioBitRate: + case KMccFilePosition: + case KMccFileAudioFourCC: + case KMccFileVideoFourCC: + { + __CONTROLLER( "CMccController::GetEndpointParameterL, file" ) + + TMccFileSourceSettingBuf fileSettingPak; + aMessage.ReadData2FromClientL( fileSettingPak ); + + if ( !source ) + { + // Static file info retrieval (i.e. filesource plugin + // is not loaded) + // + __ASSERT_ALWAYS( package().iParam2 == KMccFileInfo, + User::Leave( KErrNotReady ) ); + + TMccCodecInfo codecInfo; + CMccUlDlClient::GetCodecDefaultsL( KMccFileSourceUid, + fileSettingPak, + codecInfo ); + } + else + { + CMccDataSource* dataSource = static_cast( source ); + + dataSource->GetParameterL( package().iParam2, fileSettingPak ); + } + + aMessage.WriteDataToClientL( fileSettingPak ); + break; + } + case KMccFileFastForward: + { + __CONTROLLER( "CMccController::GetEndpointParameterL, file" ) + + __ASSERT_ALWAYS( source, User::Leave( KErrNotReady ) ); + CMccDataSource* dataSource = static_cast( source ); + TPckgBuf fastforwardSettingPak; + aMessage.ReadData2FromClientL( fastforwardSettingPak ); + dataSource->GetParameterL( package().iParam2, fastforwardSettingPak ); + aMessage.WriteDataToClientL( fastforwardSettingPak ); + break; + } + case KMccDisplayLocalVideo: + { + __CONTROLLER( "CMccController::GetEndpointParameterL, display" ) + + __ASSERT_ALWAYS( sink, User::Leave( KErrNotFound ) ); + CMccDataSink* dataSink = static_cast( sink ); + TMccVideoSinkSettingBuf displaySetting; + aMessage.ReadData2FromClientL( displaySetting ); + dataSink->GetParameterL( package().iParam2, displaySetting ); + aMessage.WriteDataToClientL( displaySetting ); + break; + } + case KMccConfigKey: + { + __CONTROLLER( "CMccController::GetEndpointParameterL, config" ) + + __ASSERT_ALWAYS( source, User::Leave( KErrNotFound ) ); + CMccDataSource* dataSource = static_cast( source ); + TBuf8 configKey; + aMessage.ReadData2FromClientL( configKey ); + dataSource->GetParameterL( package().iParam2, configKey ); + aMessage.WriteDataToClientL( configKey ); + break; + } + default: + { + User::Leave( KErrArgument ); + break; + } + } + + __CONTROLLER( "CMccController::GetEndpointParameterL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::UpdateEndpointL +// ----------------------------------------------------------------------------- +// +void CMccController::UpdateEndpointL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::UpdateEndpointL" ) + + __ASSERT_ALWAYS( iResourcePool, User::Leave( KErrNotReady ) ); + + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + HBufC8* updateVal = HBufC8::NewLC( aMessage.SizeOfData2FromClient() ); + TPtr8 ptrUpdateVal( updateVal->Des() ); + aMessage.ReadData2FromClientL( ptrUpdateVal ); + + iResourcePool->UpdateResourceL( package().iEndpointID, *updateVal ); + + CleanupStack::PopAndDestroy( updateVal ); + } + +// ----------------------------------------------------------------------------- +// CMccController::ReuseL +// ----------------------------------------------------------------------------- +// +void CMccController::ReuseL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::ReuseL" ) + TMccStreamPckg package; + aMessage.ReadData1FromClientL( package ); + + iResourcePool->ReuseL( package().iEndpointID ); + + __CONTROLLER( "CMccController::ReuseL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::ReferenceCountL +// ----------------------------------------------------------------------------- +// +void CMccController::ReferenceCountL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::ReferenceCountL" ) + TMccGenericMsgBuffer package; + aMessage.ReadData1FromClientL( package ); + + iResourcePool->ReferenceCountL( package().iEndpointID, package().iParam4 ); + + aMessage.WriteDataToClientL( package ); + + __CONTROLLER( "CMccController::ReferenceCountL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::RemoveEndpointL +// ----------------------------------------------------------------------------- +// +void CMccController::RemoveEndpointL( TUint32 aEndpointId ) + { + __CONTROLLER( "CMccController::RemoveEndpointL" ) + + RArray affectedStreams; + CleanupClosePushL( affectedStreams ); + iResourcePool->PrepareEndpointRemovalL( aEndpointId, affectedStreams ); + + // Stop all affected streams completely (i.e. ones using the endpoint) + for ( TInt i = 0; i < affectedStreams.Count(); i++ ) + { + TInt session = FindSessionL( affectedStreams[ i ].iSessionId ); + + iSessionArray[ session ]->StopL( affectedStreams[ i ].iLinkId, + affectedStreams[ i ].iStreamId, + 0 ); + + // Stream cannot be used anymore + iSessionArray[ session ]->UnuseL( affectedStreams[ i ].iLinkId, + affectedStreams[ i ].iStreamId ); + } + + CleanupStack::PopAndDestroy( &affectedStreams ); + + // Now it should be safe to finally remove the endpoint + iResourcePool->RemoveEndpointL( aEndpointId ); + + __CONTROLLER( "CMccController::RemoveEndpointL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::TranscodeFileL +// ----------------------------------------------------------------------------- +// +void CMccController::TranscodeFileL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::TranscodeFileL" ) + + TMccTranscodeFileMsgBuffer fileMsgPkg; + aMessage.ReadData1FromClientL( fileMsgPkg ); + + TMccCreateSessionPckg sessionMsgPkg; + + if ( !iTranscoder ) + { + iTranscoder = reinterpret_cast< CMccTranscoder* >( + REComSession::CreateImplementationL( + KUidMccTranscoder, iTranscoderKey ) ); + } + if ( !iTranscoder ) + { + User::Leave( KErrNotFound ); + } + + TUint32 sessionId = 0; + iTranscoder->RegisterEventObserver( *this ); + + iTranscoder->TranscodeFileL( sessionId, fileMsgPkg ); + + sessionMsgPkg().iSessionID = sessionId; + aMessage.WriteDataToClientL( sessionMsgPkg ); + + __CONTROLLER( "CMccController::TranscodeFileL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::CancelTranscodeFileL +// ----------------------------------------------------------------------------- +// +void CMccController::CancelTranscodeFileL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::CancelTranscodeFileL" ) + + TMccCreateSessionPckg pckg; + aMessage.ReadData1FromClientL( pckg ); + + if ( iTranscoder ) + { + iTranscoder->CancelTranscodeFileL( pckg().iSessionID ); + } + + __CONTROLLER( "CMccController::CancelTranscodeFileL, exit" ) + } + +// CMccController::RateAdaptationRequest +// ----------------------------------------------------------------------------- +// +TInt CMccController::RateAdaptationRequest( + const TMccEvent& /*aInputData*/, + TMccEvent& /*aOutputData*/ ) + { + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccController::RateAdaptationAlert +// ----------------------------------------------------------------------------- +// +TInt CMccController::RateAdaptationAlert( + const TMccEvent& /*aAdaptationData*/, + TAlertType /*aAlertType*/ ) + { + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccController::StoreAndSendEvent +// ----------------------------------------------------------------------------- +// +TInt CMccController::StoreAndSendEvent( const TMccEvent& aEvent ) + { + TRAPD( err, StoreEventL( aEvent ) ); + if ( !err ) + { + this->SendEvent(); + } + return err; + } + +// ----------------------------------------------------------------------------- +// CMccController::StoreEventL +// ----------------------------------------------------------------------------- +// +void CMccController::StoreEventL( const TMccEvent& aEvent ) + { + // RArray cannot be used since TMccEvent size exceeds 640 bytes + TMccEvent* event = new ( ELeave ) TMccEvent( aEvent ); + CleanupStack::PushL( event ); + iEventBuf.AppendL( event ); + CleanupStack::Pop( event ); + } + +// ----------------------------------------------------------------------------- +// CMccController::StreamActionL +// ----------------------------------------------------------------------------- +// +void CMccController::StreamActionL( + const TMccEvent& aEvent, + const TMccEvent* aAdditionalEvent ) + { + __CONTROLLER( "CMccController::StreamActionL" ) + + if ( aAdditionalEvent ) + { + __CONTROLLER( "CMccController::StreamActionL, handling additional event first" ) + + StreamActionL( *aAdditionalEvent, NULL ); + } + + switch ( aEvent.iEventType ) + { + case KMccStandbyInactivityEvent: + case KMccStreamPaused: + { + PauseByEndPointIdL( aEvent, aEvent.iEndpointId ); + break; + } + case KMccStandbyActivityEvent: + case KMccStreamResumed: + { + ResumeByEndPointIdL( aEvent, aEvent.iEndpointId ); + break; + } + default: + { + break; + } + } + + __CONTROLLER( "CMccController::StreamActionL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::CancelMmfMessage +// ----------------------------------------------------------------------------- +// +void CMccController::CancelMmfMessage() + { + if ( iMessage ) + { + iMessage->Complete( KErrCancel ); + delete iMessage; + iMessage = 0; + } + } + +// ----------------------------------------------------------------------------- +// CMccController::CreationProcessEnd +// Called by link creator when link creation process has ended +// ----------------------------------------------------------------------------- +// +void CMccController::CreationProcessEnd( const TMccCreateLinkPckg& aClientData, + CMccAsyncLinkCreator* aCreator, TInt aError ) + { + __CONTROLLER( "CMccController::CreationProcessEnd IN" ) + + + TMccNetSettings netSettings; + netSettings.iLocalAddress = aClientData().iLocalAddress; + netSettings.iLocalRtcpPort = aClientData().iLocalRtcpAddress.Port(); + netSettings.iMediaQosValue = aClientData().iIpTOS; + TMccNetSettingsPackage netSettingsPkg = netSettings; + + // Send event to client to notify that a new link is now created + TMccEvent event; + event.iSessionId = aClientData().iSessionID; + event.iLinkId = aClientData().iLinkID; + event.iEventType = KMccLinkCreated; + event.iEventData = netSettingsPkg; + event.iErrorCode = aError; + + if ( NULL != aCreator ) + { + TInt index = iCreatorArray.Find( aCreator ); + + if( KErrNotFound != index ) + { + __CONTROLLER( "CMccController::CreationProcessEnd FOUND delete" ) + iCreatorArray.Remove( index ); + } + + delete aCreator; + } + + SendMccEventToClient( event ); + } + +// ----------------------------------------------------------------------------- +// CMccController::BindContextIntoStreamL +// ----------------------------------------------------------------------------- +// +void CMccController::BindContextIntoStreamL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::BindContextIntoStreamL" ) + + TMccCryptoContextPckg cryptoContextPckg; + aMessage.ReadData1FromClientL( cryptoContextPckg ); + + TMccSecurityDestinationBuffer secDestBuf; + aMessage.ReadData2FromClientL( secDestBuf ); + + TInt session = FindSessionL( secDestBuf().iSessionID ); + + iSessionArray[ session ]->BindContextIntoStreamL( secDestBuf().iLinkID, + secDestBuf().iStreamID, + secDestBuf().iEndpointID, + cryptoContextPckg() ); + + __CONTROLLER( "CMccController::BindContextIntoStreamL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::RemoveContextL +// ----------------------------------------------------------------------------- +// +void CMccController::RemoveContextL( TMMFMessage& aMessage ) + { + __CONTROLLER( "CMccController::RemoveContextL" ) + TMccSecurityDestinationBuffer secDestBuf; + aMessage.ReadData2FromClientL( secDestBuf ); + + TInt session = FindSessionL( secDestBuf().iSessionID ); + + iSessionArray[ session ]->RemoveContextL( secDestBuf().iLinkID, + secDestBuf().iStreamID, + secDestBuf().iEndpointID ); + + __CONTROLLER( "CMccController::RemoveContextL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccController::MccTranscoderEventReceived +// ----------------------------------------------------------------------------- +// +void CMccController::MccTranscoderEventReceived( TMccEvent& aEvent ) + { + SendMccEventToClient( aEvent ); + } + +// ----------------------------------------------------------------------------- +// CMccController::AddCodec +// ----------------------------------------------------------------------------- +// +void CMccController::AddCodec( + const TUint32& aCodec, + const RArray< TFourCC >& aSupportedOutCodecs, + const RArray< TFourCC >& aSupportedInCodecs, + TFixedArray& aCodecs, + TInt aIndex ) const + { + TFourCC codec( aCodec ); + #if ( defined __WINSCW__ ) || ( defined __WINS__ ) + // In emulator, CMMFDevSound does not return the same list as in HW + aCodecs[ aIndex ] = codec; + aSupportedOutCodecs; // silence compiler warning + aSupportedInCodecs; // silence compiler warning + #else + if ( aSupportedOutCodecs.Find( codec ) >= 0 && + aSupportedInCodecs.Find( codec ) >= 0 ) + { + aCodecs[ aIndex ] = codec; + } + #endif + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File