diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccsubcontroller/src/mccrtcpreceiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccsubcontroller/src/mccrtcpreceiver.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,483 @@ +/* +* 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: RTCP Receiver class from RTP Datasource +* +*/ + + + + +// INCLUDE FILES +#include "mccrtcpreceiver.h" +#include "mccdef.h" +#include "mccinternaldef.h" +#include "mccsubcontrollerlogs.h" +#include "mccinternalevents.h" +#include "mccresources.h" +#include "mccrtpmanager.h" + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::CMccRtcpReceiver +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMccRtcpReceiver::CMccRtcpReceiver( + CMccRtpManager* aRtpManager, + MAsyncEventHandler& aEventHandler, + MMccResources& aMccResources, + CRtpAPI& aRtpAPI ) : + iStream( KNullId ), + iEventHandler( aEventHandler ), + iMccResources( aMccResources ), + iRtpAPI( aRtpAPI ), + iSessionId( KNullId ), + iRtpManager( aRtpManager ) + { + + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMccRtcpReceiver* CMccRtcpReceiver::NewL( + CMccRtpManager* aRtpManager, + MAsyncEventHandler& aEventHandler, + MMccResources& aMccResources, + CRtpAPI& aRtpAPI ) + { + CMccRtcpReceiver* self = new( ELeave ) CMccRtcpReceiver( aRtpManager, + aEventHandler, + aMccResources, + aRtpAPI ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::ConstructL( ) + { + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::~CMccRtcpReceiver +// Destructor +// ----------------------------------------------------------------------------- +// +CMccRtcpReceiver::~CMccRtcpReceiver() + { + __SUBCONTROLLER( "CMccRtcpReceiver::~CMccRtcpReceiver()" ) + + if ( iSessionId != KNullId ) + { + iRtpAPI.SetNonRTPDataObserver( iSessionId, NULL ); + } + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::HandleReceiving +// ----------------------------------------------------------------------------- +// +TInt CMccRtcpReceiver::HandleReceiving( TRtpId aSessionId, TBool aEnableReceiving ) + { + __SUBCONTROLLER( "CMccRtcpReceiver::HandleReceiving()" ) + TInt err = KErrNone; + + // TBD! Never disable (maybe disabling is needed in future) + // + aEnableReceiving = ETrue; + + if ( iEnableRtcp != aEnableReceiving ) + { + iSessionId = aSessionId; + iEnableRtcp = aEnableReceiving; + if ( iEnableRtcp ) + { + __SUBCONTROLLER( "CMccRtcpReceiver::HandleReceiving(), enabling" ) + err = iRtpAPI.RegisterRtcpObserver( iSessionId, *this ); + if ( !err ) + { + err = iRtpAPI.SetNonRTPDataObserver( iSessionId, this ); + } + } + else + { + __SUBCONTROLLER( "CMccRtcpReceiver::HandleReceiving(), disabling" ) + iRtpAPI.UnregisterRtcpObserver( iSessionId ); + iRtpAPI.SetNonRTPDataObserver( iSessionId, NULL ); + } + } + return err; + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::SdesReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::SdesReceived( TRtpSSRC aSSRC, + const TRtpSdesParams& aParams ) + { + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SdesReceived() SSRC:", aSSRC ) + + // Take copies of sdes member data and create new sdes object which will point + // to those new data. This will prevent data loss while transfering the event + // through IPC. + + TPckgBuf tempSdesPackage( aParams ); + + TInt sdesPackageLen( sizeof( tempSdesPackage ) ); + + TInt sdesLen = sdesPackageLen + + aParams.iCName.Length() + + aParams.iUserName.Length() + + aParams.iEmail.Length() + + aParams.iPhoneNumber.Length() + + aParams.iLocation.Length() + + aParams.iSwToolName.Length() + + aParams.iNoticeStatus.Length() + + aParams.iPrivate.Length(); + + if ( sdesLen <= KMccMaxRtcpPacketDataLength ) + { + ClearEventData(); + + TRtpSdesParams sdes; + iEventData.iSsrc = aSSRC; + + TUint8* currentPtr = const_cast( iEventData.iRtcpPacketData.Ptr() ); + currentPtr += sdesPackageLen; + + iEventData.iRtcpPacketData.SetLength( sdesPackageLen ); + + TInt currentPos( sdesPackageLen ); + + DoSdesMemberCopy( sdes.iCName, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iCName ); + + DoSdesMemberCopy( sdes.iUserName, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iUserName ); + + DoSdesMemberCopy( sdes.iEmail, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iEmail ); + + DoSdesMemberCopy( sdes.iPhoneNumber, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iPhoneNumber ); + + DoSdesMemberCopy( sdes.iLocation, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iLocation ); + + DoSdesMemberCopy( sdes.iSwToolName, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iSwToolName ); + + DoSdesMemberCopy( sdes.iNoticeStatus, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iNoticeStatus ); + + DoSdesMemberCopy( sdes.iPrivate, ¤tPtr, currentPos, + iEventData.iRtcpPacketData, aParams.iPrivate ); + + // Finally copy sdes into beginning of the data + TPckgBuf sdesPackage( sdes ); + iEventData.iRtcpPacketData.Insert( 0, sdesPackage ); + + SendRtcpEventToClient( KRtcpSdesPacket, ETrue, EFalse ); + } + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::ByeReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::ByeReceived( TRtpId aStreamId, + TRtpSSRC aSSRC, + const TDesC8& aReason ) + { + __SUBCONTROLLER_INT2( "CMccRtcpReceiver::ByeReceived() STREAM:", aStreamId, + "SSRC:", aSSRC ) + + iStream = aStreamId; + + SendRtcpEventWithPacketDataToClient( KRtcpByePacket, aSSRC, aReason, ETrue ); + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::AppReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::AppReceived( TRtpId aStreamId, + TRtpSSRC aSSRC, + const TRtcpApp& aApp ) + { + __SUBCONTROLLER_INT2( "CMccRtcpReceiver::AppReceived() STREAM:", aStreamId, + "SSRC:", aSSRC ) + + iStream = aStreamId; + + TPckgBuf app( aApp ); + SendRtcpEventWithPacketDataToClient( KRtcpAppPacket, aSSRC, app, ETrue ); + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::SrReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::SrReceived( TRtpId aStreamId, + TRtpSSRC aSSRC, + const TTimeStamps& aTimeStamps ) + { + __SUBCONTROLLER_INT2( "CMccRtcpReceiver::SrReceived() STREAM:", aStreamId, + "SSRC:", aSSRC ) + + iStream = aStreamId; + + ClearEventData(); + + iEventData.iSsrc = aSSRC; + iEventData.iTimeStamps = aTimeStamps; + iRtpAPI.GetStreamStatistics( iStream, iEventData.iStats ); + + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() packets sent:", iEventData.iStats.iNumPacketsSent ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() octets sent:", iEventData.iStats.iCumNumOctetsSent ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() roundtrip delay:", iEventData.iStats.iRoundTripDelay ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() tx bandwidth:", iEventData.iStats.iTxBandwidth ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() packets lost:", iEventData.iStats.iCumNumPacketsLost ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() fractions lost:", iEventData.iStats.iFractionLost ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() arrival jitter:", iEventData.iStats.iArrivalJitter ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() rx bandwidth:", iEventData.iStats.iRxBandwidth ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() channelbuffer size:", iEventData.iStats.iChannelBufferSize ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() ntp timestamp sec:", iEventData.iStats.iNTPTimeStampSec ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() ntp timestamp frac:", iEventData.iStats.iNTPTimeStampFrac ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SrReceived() timestamp:", iEventData.iStats.iTimeStamp ) + + SendRtcpEventToClient( KRtcpSrPacket, EFalse, ETrue ); + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::RrReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::RrReceived( TRtpId aStreamId, TRtpSSRC aSSRC ) + { + __SUBCONTROLLER_INT2( "CMccRtcpReceiver::RrReceived() STREAM:", aStreamId, + "SSRC:", aSSRC ) + + iStream = aStreamId; + + ClearEventData(); + + iEventData.iSsrc = aSSRC; + iRtpAPI.GetStreamStatistics( iStream, iEventData.iStats ); + + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() packets sent:", iEventData.iStats.iNumPacketsSent ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() octets sent:", iEventData.iStats.iCumNumOctetsSent ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() roundtrip delay:", iEventData.iStats.iRoundTripDelay ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() tx bandwidth:", iEventData.iStats.iTxBandwidth ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() packets lost:", iEventData.iStats.iCumNumPacketsLost ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() fractions lost:", iEventData.iStats.iFractionLost ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() arrival jitter:", iEventData.iStats.iArrivalJitter ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() rx bandwidth:", iEventData.iStats.iRxBandwidth ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() channelbuffer size:", iEventData.iStats.iChannelBufferSize ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() ntp timestamp sec:", iEventData.iStats.iNTPTimeStampSec ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() ntp timestamp frac:", iEventData.iStats.iNTPTimeStampFrac ) + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::RrReceived() timestamp:", iEventData.iStats.iTimeStamp ) + + SendRtcpEventToClient( KRtcpRrPacket, EFalse, ETrue ); + } + +// ----------------------------------------------------------------------------- +// CMccRtcpReceiver::NonRTPDataReceived() +// From MRtcpObserver +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::NonRTPDataReceived( TUint /*aPort*/, + TBool aRTPPort, + const TDesC8& aNonRTPData ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::NonRTPDataReceived()" ) + + // Currently, Non-RTP data is accepted only on the RTCP port + if ( !aRTPPort ) + { + SendRtcpEventWithPacketDataToClient( KRtcpPacketUndefined, + 0, + aNonRTPData, + EFalse ); + } + } + +// ----------------------------------------------------------------------------- +// CMccRtcpEvent::SendRtcpEventWithPacketDataToClient() +// Constructs RTCP event containing RTCP packet data and sends the event to +// client side +// ----------------------------------------------------------------------------- +// +TInt CMccRtcpReceiver::SendRtcpEventWithPacketDataToClient( + TMccRtcpPacketType aPacketType, + const TRtpSSRC& aSSRC, + const TDesC8& aData, + TBool aResolveEndpointBySsrc ) + { + if ( aData.Length() > KMccMaxRtcpPacketDataLength ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::SendRtcpEventWithPacketDataToClient(), data size too big ") + + return KErrOverflow; + } + + ClearEventData(); + + iEventData.iSsrc = aSSRC; + iEventData.iRtcpPacketData.Copy( aData ); + + SendRtcpEventToClient( aPacketType, aResolveEndpointBySsrc, EFalse ); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccRtcpEvent::SendRtcpEventToClient() +// Sends the RTCP event to client side +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::SendRtcpEventToClient( + TMccRtcpPacketType aPacketType, + TBool aResolveEndpointBySsrc, + TBool aResolveEndpointByRtpStreamId ) + { + __SUBCONTROLLER_INT1( "CMccRtcpReceiver::SendRtcpEventToClient() packetType:", aPacketType ) + + TUint32 endpointId( 0 ); + + if ( aResolveEndpointBySsrc ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::SendRtcpEventToClient(), resolve endpointId by ssrc" ) + MDataSource* source = 0; + MDataSink* sink = 0; + if ( !iMccResources.FindNetworkResourceByRtpSsrc( iEventData.iSsrc, &source, &sink ) ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::SendRtcpEventToClient(), resolved" ) + endpointId = source != 0 ? MCC_ENDPOINT_ID( source ) : + MCC_ENDPOINT_ID( sink ); + } + } + + if ( aResolveEndpointByRtpStreamId ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::SendRtcpEventToClient(), resolve endpointId by streamId" ) + MDataSource* source = 0; + MDataSink* sink = 0; + if ( !iMccResources.FindNetworkResourceByRtpStreamId + ( iRtpManager->MccSessionId(), iStream, &source, &sink ) ) + { + __SUBCONTROLLER( "CMCCRtcpReceiver::SendRtcpEventToClient(), resolved" ) + endpointId = source != 0 ? MCC_ENDPOINT_ID( source ) : + MCC_ENDPOINT_ID( sink ); + } + } + + iEventData.iRtcpPacketType = aPacketType; + + TMccEvent event; + event.iEventCategory = KMccEventCategoryRtcp; + event.iEventType = KMccRtcpReceived; + event.iEndpointId = endpointId; + + // Save some stack memory + { + event.iEventData.Copy( TMccRtcpEventDataPackage( iEventData ) ); + } + + TMccInternalEvent internalEvent( KMccRtpSourceUid, + EMccInternalEventNone, + event ); + + // Stream id, link id and session id will be filled on the way up + iEventHandler.SendEventToClient( internalEvent ); + } + +// ----------------------------------------------------------------------------- +// CMccRtcpEvent::DoSdesMemberCopy() +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::DoSdesMemberCopy( + TPtrC8& aDestination, + TUint8** aCurrentPtr, + TInt& aCurrentPos, + TDes8& aRtcpPacketData, + const TDesC8& aSource ) + { + TInt len( aSource.Length() ); + + if ( aCurrentPos + len <= aRtcpPacketData.MaxLength() ) + { + aRtcpPacketData.Insert( aCurrentPos, aSource ); + + aDestination.Set( *aCurrentPtr, len ); + + *aCurrentPtr += len; + aCurrentPos += len; + } + else + { + aDestination.Set( *aCurrentPtr, 0 ); + } + } + +// ----------------------------------------------------------------------------- +// CMccRtcpEvent::ClearEventData() +// ----------------------------------------------------------------------------- +// +void CMccRtcpReceiver::ClearEventData() + { + iEventData = TMccRtcpEventData(); + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File