rtp/rtpstack/src/rtpsessionsrtp.cpp
changeset 0 307788aac0a8
child 19 b5e99d8877c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtp/rtpstack/src/rtpsessionsrtp.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,430 @@
+/*
+* Copyright (c) 2002-2003 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:    
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "rtpsessionsrtp.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ---------------------------------------------------------------------------
+//
+CRtpSessionSrtp::CRtpSessionSrtp( const TRtpId aSessionId,
+                          const TUint32* aProfileRTPTimeRates,
+                          const TBool aStandardRtp,
+                          MRtpErrNotify& aErrNotify,
+                          const CRtpSDES* aSdesInfo , 
+                          MRtpAsignUniqueID& aAssignUniqueID,
+                          CSRTPSession& aSRTPSession) 
+    :CRtpSession( aSessionId,
+                  aProfileRTPTimeRates,
+                 aStandardRtp, aErrNotify,
+                 aSdesInfo, aAssignUniqueID),
+     iSRTPSession( aSRTPSession ),
+     iSndPacket(NULL),
+     iSndRtcpPacket(NULL)
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CRtpSessionSrtp::ConstructL( const TCreateSessionParams& aParams,
+                              TUint& aPort,
+                              TBool aEnableRtcp,
+                              const TRtcpParams* aRtcpParams,
+                              RSocketServ& aSocketServ,
+                              RConnection& aRConn,
+                              const RLibrary& aLibrary,
+                              MRtpErrNotify& aErrNotify )
+    {
+    CRtpSession::ConstructL( aParams, aPort, aEnableRtcp, aRtcpParams, aSocketServ, 
+                      aRConn, aLibrary, aErrNotify );
+    iIsSrtp=ETrue;                  
+    }
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CRtpSessionSrtp* CRtpSessionSrtp::NewL( const TCreateSessionParams& aParams,
+                                TUint& aPort,
+                                TBool aEnableRtcp,
+                                const TRtcpParams* aRtcpParams,
+                                RSocketServ& aSocketServ,
+                                RConnection& aRConn,
+                                const TRtpId aSessionId,
+                                const CRtpSDES* aSdes, // application's SDES
+                                const TUint32* aProfileRTPTimeRates,
+                                const TBool aStandardRtp,
+                                const RLibrary& aLibrary,
+                                MRtpErrNotify& aErrNotify, 
+                                MRtpAsignUniqueID& aAssignUniqueID,
+                                CSRTPSession& aSRTPSession )
+    {
+    CRtpSessionSrtp* self = new ( ELeave ) CRtpSessionSrtp( aSessionId, 
+                                                    aProfileRTPTimeRates,
+                                                    aStandardRtp, aErrNotify,
+                                                    aSdes,aAssignUniqueID,
+                                                    aSRTPSession);
+    CleanupStack::PushL( self );
+    self->ConstructL( aParams, aPort, aEnableRtcp, aRtcpParams, aSocketServ, 
+                      aRConn, aLibrary, aErrNotify );
+    CleanupStack::Pop(); // self 
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CRtpSessionSrtp::~CRtpSessionSrtp()
+    {
+    
+ 	delete iSndPacket; iSndPacket=NULL;
+ 	delete iRecvPacket; iRecvPacket=NULL;
+ 	if(iSndRtcpPacket)
+ 		delete iSndRtcpPacket; iSndRtcpPacket=NULL;
+ 	if(iRecvRtcpPacket)
+ 		delete iRecvRtcpPacket;iRecvRtcpPacket=NULL;
+    }
+    
+                          
+// ---------------------------------------------------------------------------
+// CRtpSessionSrtp::SendRtpPacket
+// ---------------------------------------------------------------------------
+//
+            
+TInt CRtpSessionSrtp::SendRtpPacket( TRtpId aTranStreamId, 
+						const TRtpSendHeader& aHeaderInfo, 
+                        const TDesC8& aPayloadData )
+	{
+    if ( static_cast<TUint> (aPayloadData.Size()) > iCommNet->MaxSocketSize() )
+    	{
+    	return KErrOverflow;
+    	}
+
+    // find stream
+    TUint streamAddress = 0;
+    TInt ret( FindStream( aTranStreamId, streamAddress ) );
+
+    if ( ret == KErrNone )
+        {
+        CRtpTranStream* tempStream = ( CRtpTranStream* ) streamAddress;
+        tempStream->BuildRtpPacket( aHeaderInfo, aPayloadData, 0, EFalse,
+                                    iPktSnd );
+ 
+		if(iSndPacket)
+			{
+			delete iSndPacket;
+			iSndPacket=NULL;
+			}
+		TRAPD( error, iSndPacket =iSRTPSession.ProtectRTPL(tempStream->GetLocalSSRC(), iPktSnd->Des()));
+		if(error==KErrNone)
+			{
+			return error = iCommNet->Send( ERTPPort, *iSndPacket);
+			}
+		return error;	
+        }
+    return ret;
+	
+	}
+                          
+// ---------------------------------------------------------------------------
+// CRtpSessionSrtp::SendRtpPacket
+// ---------------------------------------------------------------------------
+//
+        
+        
+TInt CRtpSessionSrtp::SendRtpPacket( TRtpId aTranStreamId,
+                            const TRtpSendHeader& aHeaderInfo,
+                            const TDesC8& aPayloadData,
+                            TRequestStatus& aStatus )
+	{
+	if ( static_cast<TUint> (aPayloadData.Size()) > iCommNet->MaxSocketSize() )
+    	{
+    	return KErrOverflow;
+    	}
+
+    // find stream
+    TUint streamAddress = 0;
+    TInt ret( FindStream( aTranStreamId, streamAddress ) );
+
+    if ( ret == KErrNone )
+        {
+        CRtpTranStream* tempStream = ( CRtpTranStream* ) streamAddress;
+        tempStream->BuildRtpPacket( aHeaderInfo, aPayloadData, 0, EFalse,
+                                    iPktSnd );
+        if(iSndPacket)
+        	{
+        	delete iSndPacket;
+        	iSndPacket=NULL;
+        	}
+        	
+        TRAPD(error, iSndPacket =iSRTPSession.ProtectRTPL(tempStream->GetLocalSSRC(), iPktSnd->Des()));
+        if(error==KErrNone)
+       		{
+       		iCommNet->Send( ERTPPort, *iSndPacket, aStatus );
+       		}
+       	return error;	
+        }
+    return ret;
+	}
+
+
+// ---------------------------------------------------------------------------
+// CRtpSessionSrtp::SendRtpPacket
+// ---------------------------------------------------------------------------
+//
+
+        
+TInt CRtpSessionSrtp::SendRtpPacket( TRtpId aTranStreamId,
+                            TRtpSequence aSequenceNum,
+                            const TRtpSendHeader& aHeaderInfo,
+                            const TDesC8& aPayloadData,
+                            TRequestStatus& aStatus )
+	{
+    if ( static_cast<TUint>( aPayloadData.Size() ) > iCommNet->MaxSocketSize() )
+    	{
+    	return KErrOverflow;
+    	}
+
+    // find stream
+    TUint streamAddress = 0;
+    TInt ret( FindStream( aTranStreamId, streamAddress ) );
+
+    if ( ret == KErrNone )
+        {
+        CRtpTranStream* tempStream =
+            reinterpret_cast<CRtpTranStream*>( streamAddress );
+        tempStream->BuildRtpPacket( aHeaderInfo, aPayloadData, aSequenceNum,
+                                    ETrue, iPktSnd );
+        if(iSndPacket)
+        	{
+        	delete iSndPacket;
+        	iSndPacket=NULL;
+        	}
+        TRAPD( error, iSndPacket =iSRTPSession.ProtectRTPL(tempStream->GetLocalSSRC(), iPktSnd->Des()));
+        if(error==KErrNone)
+       		{
+        	iCommNet->Send( ERTPPort, *iSndPacket, aStatus );	
+        	}
+        return error;	
+        }
+    return ret;
+	}
+
+ // ---------------------------------------------------------------------------
+// CRtpSessionSrtp::OnRtpReceivedL
+// ---------------------------------------------------------------------------
+//       
+   
+void CRtpSessionSrtp::OnRtpReceivedL()
+	{
+	RTP_DEBUG_DETAIL( "CRtpSessionSrtp::OnRtpReceivedL Entry" );
+    	
+	TRtpSSRC ssrc(0);
+	FindRtpRxStreamSSRC(ssrc);
+	if( ssrc!=0 )
+		{
+		//should always has one recv to match it so ssrc should not be zero
+		if( UnprotectRtp(ssrc)==KErrNone )	
+			{
+			RTP_DEBUG_DETAIL( "Decrypted RTP data succeed" );
+			CRtpSession::OnRtpReceivedL();	
+			}
+		else //packet is not successful decrypted
+			{
+			RTP_DEBUG_DETAIL( "Decrypted RTP data failed" );
+    	//pass as non-rtp data to application instead of droping msg IssueRtpRecv(); 
+			//including STUN and FC messages
+			if (iNonRTPDataObserver)
+            	{
+            	// notify user
+            	RTP_DEBUG_DETAIL( "Notify decrypted failed RTP data as non rtp data" );
+            	iNonRTPDataObserver->NonRTPDataReceived(GetRtpSocket()->LocalPort(), 
+                                    ETrue, iRtpRecvBuf);
+            	} 
+            IssueRtpRecv();  	                          
+			}	
+		
+		}
+	else
+		{
+		//pass as non-rtp data to application
+		//including STUN and FC messages
+		RTP_DEBUG_DETAIL( "Encrypted incoming Packet SSRC is not found from RX streams" );
+    
+		if (iNonRTPDataObserver)
+            {
+            // notify user
+            RTP_DEBUG_DETAIL( "Notify non rtp data" );
+            	
+            iNonRTPDataObserver->NonRTPDataReceived(GetRtpSocket()->LocalPort(), 
+                                   ETrue, iRtpRecvBuf);
+            }   
+        IssueRtpRecv();      
+		}
+	RTP_DEBUG_DETAIL( "CRtpSessionSrtp::OnRtpReceivedL Exit" );
+	}
+ 
+ // ---------------------------------------------------------------------------
+// CRtpSessionSrtp::OnRtpReceived
+// ---------------------------------------------------------------------------
+//       
+   
+TInt CRtpSessionSrtp::UnprotectRtp(TRtpSSRC ssrc)
+	{	
+		//should always has one recv to match it so ssrc should not be zero
+	if(iRecvPacket)
+		{
+		delete iRecvPacket;
+		iRecvPacket = NULL;	
+		}	
+	TRAPD( err, iRecvPacket= iSRTPSession.UnprotectRTPL(ssrc, iRtpRecvBuf); );		
+	if(err==KErrNone)
+		{
+		iRtpRecvBuf=*iRecvPacket/*iRecvPacket->Des()*/;		
+		}
+	
+	return err;
+	
+	}
+ 
+// ---------------------------------------------------------------------------
+// CRtpSessionSrtp::SendRTCPReport()
+// 
+// ---------------------------------------------------------------------------
+//
+void CRtpSessionSrtp::SendSRTCPReportL(TRtpSSRC aSSRC)
+    {
+    TInt err= KErrNone;
+    if ( !iRtcpEnabled )
+        {
+        return;
+        }
+    if (iSndRtcpPacket)
+    	{
+    	delete iSndRtcpPacket;
+    	iSndRtcpPacket=NULL;
+    	}
+    TRAPD( error, 
+    iSndRtcpPacket =iSRTPSession.ProtectRTCPL(aSSRC, iPktRtcpSnd->Des()));    
+    
+    if ( error==KErrNone && iSndRtcpPacket )
+        {
+        err =iCommNet->Send( ERTCPPort, *iSndRtcpPacket );
+        if (err  == KErrDisconnected)
+        		( void ) StopRtcpSending();
+        AverageRtcpSize( iSndRtcpPacket->Size() );
+        	
+        }
+    // update RTCP average packet size
+    
+    iPktRtcpSnd->RtpPacketReset();
+    }
+
+ // ---------------------------------------------------------------------------
+// CRtpSessionSrtp::OnRtcpReceived
+// ---------------------------------------------------------------------------
+//       
+void CRtpSessionSrtp::OnRtcpReceivedL()
+    {
+    RTP_DEBUG_DETAIL( "CRtpSessionSrtp::OnRtcpReceivedL Entry" );
+    
+    if ( !iRtcpEnabled )
+        {
+        RTP_DEBUG_DETAIL( "No RTCP obs" );
+        return;
+        }
+    TRtpSSRC sourceSSRC( NULL );
+    iPktRtcpRcv->SetSize( iRtcpRecvBuf.Size() );
+
+    // set packet pointer to the beginning
+    iPktRtcpRcv->RtpPacketResetPtr();
+
+    // parse RTCP packet header    
+    iPktRtcpRcv->SetType( ERTCP_HEADER );
+    // Get SSRC of packet sender for this report
+    // (This operation does not move the packet pointer)
+    sourceSSRC = iPktRtcpRcv->RtpPacketGetSSRC(); 
+	if( sourceSSRC!=0 )
+		{
+		//should always has one recv to match it so ssrc should not be zero
+		if( UnprotectRtcp(sourceSSRC) == KErrNone )	
+			{
+			RTP_DEBUG_DETAIL( "Decrypted RTCP successful" );
+            	
+			CRtpSession::OnRtcpReceivedL();	
+			}
+		else //packet is not successful decrypted
+			{
+			if (iNonRTPDataObserver )
+				{
+				RTP_DEBUG_DETAIL( "Notify decrypted failed RTP data as non rtp data" );
+            	
+				iNonRTPDataObserver->NonRTPDataReceived(GetRtcpSocket()->LocalPort(), 
+												EFalse,
+                                                iRtcpRecvBuf);	
+				}
+			IssueRtcpRecv();
+			}	
+		
+		}
+	else
+		{
+		RTP_DEBUG_DETAIL( "Encrypted incoming Packet SSRC is not found from RX streams" );
+    	if (iNonRTPDataObserver )
+				{
+				iNonRTPDataObserver->NonRTPDataReceived(GetRtcpSocket()->LocalPort(), 
+												EFalse,
+                                                iRtcpRecvBuf);
+				}
+		IssueRtcpRecv();		
+		}
+  
+    }
+    
+// ---------------------------------------------------------------------------
+// CRtpSessionSrtp::UnprotectRtcp
+// ---------------------------------------------------------------------------
+//       
+   
+TInt CRtpSessionSrtp::UnprotectRtcp(TRtpSSRC ssrc)
+	{	
+		//should always has one recv to match it so ssrc should not be zero
+
+	if(iRecvRtcpPacket)
+		{
+		delete iRecvRtcpPacket;	iRecvRtcpPacket=NULL;
+		}
+	TRAPD( err, iRecvRtcpPacket= iSRTPSession.UnprotectRTCPL(ssrc, *(iPktRtcpRcv->GetHBuf())); );		
+	if(err==KErrNone)
+		{
+		iRtcpRecvBuf=*iRecvRtcpPacket;		
+		}
+		
+	return err;
+		
+	}
+