--- /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<TRtpSdesParams> 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<TUint8*>( 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<TRtpSdesParams> 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<TRtcpApp> 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