multimediacommscontroller/mmccMsrppayloadformat/src/Msrppayloadformatread.cpp
branchrcs
changeset 49 64c62431ac08
child 50 1d8943dd8be6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccMsrppayloadformat/src/Msrppayloadformatread.cpp	Mon Sep 06 17:32:13 2010 +0530
@@ -0,0 +1,1230 @@
+/*
+* Copyright (c) 2004-2006 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:    Provides a comfort noise generator class
+*
+*/
+
+
+// INCLUDE FILES
+#include <E32base.h>
+#include <mmffourcc.h>
+#include <mmfdatabuffer.h>
+#include 	<utf.h> // charconv.lib
+
+#include "MsrpPayloadFormatRead.h"
+#include "MsrpPayloadFormatWrite.h" // TStringElement, move independent
+#include "MccRtpDataSource.h"
+#include "Mccinternaldef.h"
+#include "MccMsrpFormatLogs.h"
+#include "msrppayloadformatdefs.h"  
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+const TUint KLostChar = 0xFFFD;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CMsrpPayloadFormatRead
+//
+// CMsrpPayloadFormatRead default constructor, can NOT contain Msrp code,
+// that might leave
+// Phase #1 of 2-phase constructor
+// -----------------------------------------------------------------------------
+//
+CMsrpPayloadFormatRead::CMsrpPayloadFormatRead ( ) : iFirstPacketsMissing (EFalse),
+iPacketSecNumber(EFalse)
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::ConstructL ( MDataSource* aSource )
+    {
+    
+   	DP_MSRP_WRITE( "CMsrpPayloadFormatRead::ConstructL" );
+    __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) ); 
+ 
+ 		// we are coming downstream, the clip is now the source and
+ 		// datapath the sink. If we use RTP source if of source the RTPSource
+
+    iRtpDataSource = aSource;  
+    iClip = aSource;
+    
+    //Flags to indicate actions
+	iFillRequested = EFalse;	 
+	iBufferToReadExists = EFalse; 
+		
+    iFourCC = KMccFourCCIdMSRP ;
+    //iFourCC.Set( TFourCC( 'T','1','4','0' ) );
+    
+    iRedData = new(ELeave)CArrayFixFlat<TStringElement>(3);
+    TStringElement empty;
+    iRedData->AppendL(empty);
+    iRedData->AppendL(empty);
+    iRedData->AppendL(empty);
+		
+	// TODO : refine my sizes
+	iCharData = HBufC8::NewL( KDataSize );
+	iDecodedBuffer = CMMFDataBuffer::NewL( KRedHeaderSize +  KDataSize );
+		
+    // Initialize decoding state machine 
+    iStateMachine = CFormatDecodeStateMachine::NewL( this );
+    iStateMachine->ChangeState( EDecodeIdle );
+    
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::NewL
+// Two-phased constructor.
+// Static function for creating and constructing an instance of 
+// the Text/Msrp Format
+// Returns:  CMsrpPayloadFormatRead* : pointer to created instance
+// -----------------------------------------------------------------------------
+//
+CMsrpPayloadFormatRead* CMsrpPayloadFormatRead::NewL(
+	MDataSource* aSource )
+	
+    {
+     
+		DP_MSRP_WRITE("CMsrpPayloadFormatRead::NewL"); 
+
+		__ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
+ 
+		//__ASSERT_ALWAYS( ( KMccRtpSourceUid == aSource->DataSourceType() ||
+		//           KMccMsrpSourceUid == aSource->DataSourceType() ), 
+		//         User::Leave( KErrArgument ) );
+		CMsrpPayloadFormatRead* self = new ( ELeave ) CMsrpPayloadFormatRead;
+		CleanupStack::PushL ( self );
+		self->ConstructL ( aSource );
+		CleanupStack::Pop( self );
+		return self;
+    
+    }
+    
+   
+   
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::~CMsrpPayloadFormatRead
+//
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CMsrpPayloadFormatRead::~CMsrpPayloadFormatRead( )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::~CMsrpPayloadFormatRead");
+   	delete iFrameBufferOne;
+    delete iFrameBufferTwo;
+    
+    if ( iSourceBufOwnership )
+        {
+        delete iPayloadBuffer;
+        }
+    else
+        {
+        iPayloadBuffer = NULL;
+        }
+    
+    if(iRedData)
+        {
+        delete iRedData;
+        iRedData = NULL;
+        }
+    
+    if(iCharData)
+        {
+        delete iCharData;
+        iCharData = NULL;
+        }
+    
+    if(iDecodedBuffer)
+        {
+        delete iDecodedBuffer;
+        iDecodedBuffer = NULL;
+        }
+    
+    if ( iStateMachine )
+        {
+        iStateMachine->Cancel( );
+        delete iStateMachine;
+        }
+    iCurrentBuffer = NULL;
+    iRtpDataSource = NULL;
+    iClip = NULL;
+    iDataPath = NULL;
+    iEventHandler = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::Streams
+// Return number of message streams for the given media
+// -----------------------------------------------------------------------------
+//
+TUint CMsrpPayloadFormatRead::Streams( TUid /*aMediaType*/) const
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::Streams");
+    return 1;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::FrameTimeInterval
+// Return the frame time interval for the given media
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMsrpPayloadFormatRead::FrameTimeInterval( 
+    TMediaId /*aMediaId*/ ) const
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::FrameTimeInterval");
+        
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::
+// Fill Buffer. If DataSink asks to Fill a buffer
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::FillBufferL( CMMFBuffer* aBuffer, 
+                                         MDataSink*  aConsumer, 
+                                         TMediaId    aMediaId )
+    {
+	   	DP_MSRP_WRITE("CMsrpPayloadFormatRead::FillBufferL");
+	    __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+	    __ASSERT_ALWAYS( aBuffer->Type() == KUidMmfDataBuffer, User::Leave( KErrArgument ) );
+	    __ASSERT_ALWAYS( aConsumer, User::Leave( KErrArgument ) );
+	    __ASSERT_ALWAYS( iStateMachine, User::Leave( KErrArgument ) );
+	    __ASSERT_ALWAYS( iFrameBufferOne, User::Leave( KErrArgument ) );
+	    __ASSERT_ALWAYS( iFrameBufferTwo, User::Leave( KErrArgument ) );
+	
+	    iDataPath = aConsumer;
+	    iMediaId = aMediaId;
+	    iFillRequested = ETrue;
+
+	if ( iCurrentBuffer )
+		{
+		iCurrentBuffer->SetStatus( EAvailable );
+		iCurrentBuffer = NULL;		
+		}
+
+	if (iFrameBufferOne->Status() == EFull )
+		{
+		iCurrentBuffer = iFrameBufferOne;
+        iStateMachine->ChangeState( ESourceDataReady );				
+		}
+	else if (iFrameBufferTwo->Status() == EFull )
+		{
+		iCurrentBuffer = iFrameBufferTwo;
+        iStateMachine->ChangeState( ESourceDataReady );		
+		}
+    else
+        {
+        FillSourceBufferL();
+        } 
+//		ResetBuffers();
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::FillSinkBuffer
+// Read RTP payload and convert it into Text/Msrp Data
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::FillSinkBufferL()
+    {
+  	
+  	// reset all bufs
+    ResetPacketBuffers();
+    const TDesC8& srcBuf( iCurrentBuffer->Data() );
+    
+  	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iPacketCount: %d ", iPacketCount );
+  	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iFirstPacketsMissing: %d ", iFirstPacketsMissing );
+  	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iSatisfySecNumber: %d ", iSatisfySecNumber );
+  	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iLevelsMissing: %d ", iLevelsMissing );
+  	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iDroppedPacketCount: %d ", iDroppedPacketCount );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, iCurrentBuffer Size() : %d ", iCurrentBuffer->Data().Size() );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FillSinkBufferL, Currentbuffer BufferSize() : %d ", iCurrentBuffer->BufferSize() );
+     
+    
+    // Do not forward zero length buffers, even though we filtered all unwanted data
+    // allready in BufferFilledL() -method
+    if ( iCurrentBuffer->BufferSize() > 0 )
+        {
+       
+            TInt pValue(0); 
+		    switch ( iCodecInfo.iRedundancyCount )  
+		    {
+		    		case 0:
+		    			iDecodedBuffer->Data().Append( iCurrentBuffer->Data() );
+		    			iSatisfySecNumber++;
+		    		break;
+		    		
+		    		case 2:
+			    		pValue = DecodePayloadL( srcBuf );
+			    		User::LeaveIfError(HandleRedundancyL(pValue)); 
+		    		break;
+		    }
+                
+		if ( !pValue )
+			{
+			iStateMachine->ChangeState( EEmptyDataToSink );	
+			}
+		else
+			{
+	        FillSourceBufferL();
+			}
+        }
+    else
+    	{  
+    	// No payload or Data sent by SipCon1, ask for more
+    	DP_MSRP_WRITE("CMsrpPayloadFormatRead::FillSinkBufferL - Empty Data");
+        iStateMachine->ChangeState( EWaitSourceData );                           
+        }
+    }
+
+ 
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::ResetBuffers()
+// Send fill buffer request to RTP Data Source
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::ResetBuffers()
+{
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::ResetBuffers");
+	if ( iCurrentBuffer ) 
+		{
+		iCurrentBuffer->SetStatus( EAvailable );
+		iCurrentBuffer = NULL;		
+		}
+
+	if (iFrameBufferOne->Status() == EFull )
+		{
+		DP_MSRP_WRITE("CMsrpPayloadFormatRead::ResetBuffers() - FB1 - was FULL");
+		iCurrentBuffer = iFrameBufferOne;
+		iStateMachine->ChangeState( ESourceDataReady );				
+		}
+	else if (iFrameBufferTwo->Status() == EFull )  
+		{
+		DP_MSRP_WRITE("CMsrpPayloadFormatRead::ResetBuffers() - FB2 - was FULL");
+		iCurrentBuffer = iFrameBufferTwo;
+		iStateMachine->ChangeState( ESourceDataReady );		
+		}
+	else
+		{
+		iStateMachine->ChangeState( EWaitSourceData ); 
+		} 
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::FillSourceBufferL
+// Send fill buffer request to RTP Data Source
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::FillSourceBufferL()
+    { 
+    	
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::FillSourceBufferL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iPayloadBuffer, User::Leave( KErrArgument ) );
+
+    iClip->FillBufferL(iPayloadBuffer, this, iMediaId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SendDataToSinkL
+// Send full frame buffer to Data Path
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SendDataToSinkL( )
+    {
+		
+	DP_MSRP_WRITE("CMsrpPayloadFormatRead::SendDataToSinkL()");
+    iFillRequested = EFalse;
+    iDataPath->BufferFilledL( iDecodedBuffer );
+   
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CreateSourceBufferL
+// Create a source buffer for the given media and indicate in aReference if 
+// buffer is created.
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CMsrpPayloadFormatRead::CreateSourceBufferL( 
+    TMediaId /*aMediaId*/, 
+    TBool &aReference )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::CreateSourceBufferL");
+    // the source buffers belong to MsrpPayloadFormatRead not to datapath
+    // aReference should be set to ETrue and destroyed by MsrpPayloadFormatRead 
+    // itself.
+    aReference = ETrue;
+    iCurrentBuffer = iFrameBufferOne;
+    return iFrameBufferOne; 
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CreateSourceBufferL
+// Create a source buffer for the given media, setting frame size to match
+// the given sink buffer
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CMsrpPayloadFormatRead::CreateSourceBufferL(
+    TMediaId aMediaId,
+    CMMFBuffer& /*aSinkBuffer*/, 
+    TBool &aReference )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::CreateSourceBufferL");
+    return CreateSourceBufferL( aMediaId, aReference );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourceDataTypeCode
+// Return the source data type ( four CC code ) for the given media
+// -----------------------------------------------------------------------------
+//
+TFourCC CMsrpPayloadFormatRead::SourceDataTypeCode( 
+	TMediaId aMediaId )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourceDataTypeCode");
+    //TODO: Change me when platform supports
+	if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+		{
+		return iFourCC;
+		}
+	else
+		{
+		return TFourCC( ); //defaults to 'NULL' fourCC
+		}
+	    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SetSourceDataTypeCode
+// Set the source data type to the given four CC code for the given 
+// media
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::SetSourceDataTypeCode( TFourCC aSourceFourCC, 
+    											   TMediaId aMediaId )
+    {
+    
+	//TODO Change me when platform supports
+	/*
+	if ( KUidMediaTypeAudio != aMediaId.iMediaType ) 
+		{
+		return KErrNotSupported;
+		}
+	*/
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SetSourceDataTypeCode");
+    iFourCC = aSourceFourCC;
+    iMediaId = aMediaId;
+    iClip->SetSourceDataTypeCode( iFourCC, iMediaId );
+    return KErrNone;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourceThreadLogon
+// Log in to the source thread
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::SourceThreadLogon( 
+    MAsyncEventHandler& aEventHandler )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourceThreadLogon");
+   	iEventHandler = &aEventHandler;
+    iClip->SourceThreadLogon( aEventHandler );
+    return KErrNone;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::NegotiateSourceL( MDataSink& aDataSink )
+// Negotiate source settings to match data sink object.
+// Re-size frame buffers if needed
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::NegotiateSourceL( MDataSink& /*aDataSink*/ )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::NegotiateSourceL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    iClip->NegotiateSourceL( *this );
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourceThreadLogoff
+// Log out of the source thread.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SourceThreadLogoff()
+    {  
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourceThreadLogoff");
+	iClip->SourceThreadLogoff( );
+    }
+ 
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::FilterUnwantedData 
+// this method can be used to filter unwanted data off
+//
+// e.g SipCon1 sends BOM data in first String and PS data as carriage return
+// Engine should NOT touch these but Presentation layer should take care of these
+
+// Method can be used to filtering pusposes if needed
+// -----------------------------------------------------------------------------
+//
+TBool CMsrpPayloadFormatRead::FilterUnwantedData(const TDesC8& aBuffer)
+{
+
+	//TODO: We must do a entity recognizer, which handles this kind of data
+	// This does not affect to actual formatter, instead we
+	// a) must do it to application side
+	// b) we must define an interface, which can be called
+	TBool ret = ETrue; 
+	DP_MSRP_WRITE2("CMsrpPayloadFormatRead::FilterUnwantedData() - BufferSize:%d",aBuffer.Length()); 
+	
+	//get Three first or Three last chars
+	if( aBuffer.Length() >= 3 )
+	{
+		//SipCon sends BOM for the first time
+		TPtrC8 pBOM = aBuffer.Left(3);
+		if ( pBOM[0] == 0xEF && pBOM[1] == 0xBB && pBOM[2]== 0xBF)
+		{
+			//return EFalse if want to filter the whole message
+			ret = ETrue;
+		}
+		
+	
+		// last are unicode PS char ( return )
+		TPtrC8 pPS = aBuffer.Right(3);
+		if ( pPS[0] == 0xE2 && pPS[1] == 0x80 && pPS[2]== 0xA8)
+		{
+			//return EFalse if want to filter
+			ret = ETrue;
+		}
+	
+	}
+	//There might be back spaces and other marks
+	else if( aBuffer.Length() >= 1 )
+	{
+		TPtrC8 pChar = aBuffer.Left(1);
+		if( pChar[0] == 0x08 )
+			{
+				ret = ETrue;
+			}
+		//bell
+		else if( pChar[0] == 0x07)
+			{
+				ret = ETrue;
+			}
+		//tab
+		else if( pChar[0] == 0x09)
+			{
+				ret = ETrue;
+			}
+		//escape
+		else if( pChar[0] == 0x1B)
+			{
+				ret = ETrue;
+			}
+
+		//etc
+	}
+	
+	return ret;
+}
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::BufferFilledL
+// Called after the data buffer is filled. Update the number of bytes read
+// and the current read position for the next read operation.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::DataBufferFilledL( CMMFBuffer* aBuffer, 
+                                           const TRtpRecvHeader& aRtpHeader )
+    { 
+     
+     DP_MSRP_WRITE2("CMsrpPayloadFormatRead::SendDataToSinkL() - BufferSize:%d",aBuffer->BufferSize()); 
+     
+   	__ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( aBuffer->Type() == KUidMmfDataBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iStateMachine, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iFrameBufferOne , User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iFrameBufferTwo , User::Leave( KErrArgument ) );
+		
+	
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::BufferFilledL with RTP header param:");
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iPadding: %d", aRtpHeader.iPadding );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iExtension: %d", aRtpHeader.iExtension );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iCsrcCount: %d", aRtpHeader.iCsrcCount );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iMarker: %d", aRtpHeader.iMarker );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iPayloadType: %d", aRtpHeader.iPayloadType );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iSeqNum: %d", aRtpHeader.iSeqNum );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iTimestamp: %d", aRtpHeader.iTimestamp );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iHeaderExtension: %d", (TInt)aRtpHeader.iHeaderExtension );
+    DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iCsrcList: %d", (TInt)aRtpHeader.iCsrcList );
+	 
+	 // Do not forward smaller zero length buffers or unwanted data
+    if ( aBuffer->BufferSize() > 0 && FilterUnwantedData(static_cast<CMMFDataBuffer*>( aBuffer )->Data()) )
+    {
+		//check seqnumber, if first packet get sequence Nr. from it
+		if ( iPacketCount == 0 )
+		{
+			//if marker == 1, then we know this is the first packet
+			if(aRtpHeader.iMarker == 1)
+				{
+					// flag to indicate, because first of idle sends this also
+					if ( !iPacketSecNumber )
+						{
+						iSatisfySecNumber =	aRtpHeader.iSeqNum;
+						iCheckSum = iSatisfySecNumber;
+						iPacketSecNumber = ETrue;
+						}
+				}
+			else
+				{
+				// first packet was missing, signal this
+				iFirstPacketsMissing = ETrue;
+				DP_MSRP_WRITE("First Packet Is MISSING!");
+				}
+				
+		}
+		else 
+		{
+			// 0, -1, -2; ( 0 means expected packet arrived )
+			//iLevelsMissing = iSatisfySecNumber - aRtpHeader.iSeqNum;
+            iLevelsMissing = 0; 
+			DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iLevelsMissing: %d", iLevelsMissing );
+			DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL aRtpHeader.iSeqNum: %d", aRtpHeader.iSeqNum );
+			DP_MSRP_WRITE2("CMsrpPayloadFormatRead::BufferFilledL iSatisfySecNumber: %d", iSatisfySecNumber );
+		}
+	
+	
+	iPacketCount++;
+	// check for packets arriving late, redundant data allready got 
+	if ( iLevelsMissing <= 0)
+	{
+	    // we add packet count here. This is for physical packets, not for redundant data
+	   	
+	    if ( iFrameBufferOne->Status() == EAvailable )
+	        {
+			    iFrameBufferOne->Data().Copy( static_cast<CMMFDataBuffer*>( aBuffer )->Data() );
+			    iFrameBufferOne->SetTimeToPlay( aRtpHeader.iTimestamp );
+				iFrameBufferOne->SetLastBuffer( aRtpHeader.iMarker );
+				iFrameBufferOne->SetFrameNumber( aRtpHeader.iSeqNum );
+				iFrameBufferOne->SetStatus( EFull );
+
+	        if (iFrameBufferTwo->Status() == EAvailable )
+	        	{
+	        	iCurrentBuffer = iFrameBufferOne;
+	        	iStateMachine->ChangeState( ESourceDataReady );
+	        	}
+	        }
+	    else if ( iFrameBufferTwo->Status() == EAvailable )
+	        {
+			    iFrameBufferTwo->Data().Copy( static_cast<CMMFDataBuffer*>( aBuffer )->Data() );
+			    iFrameBufferTwo->SetTimeToPlay( aRtpHeader.iTimestamp );  
+				iFrameBufferTwo->SetLastBuffer( aRtpHeader.iMarker );
+				iFrameBufferTwo->SetFrameNumber( aRtpHeader.iSeqNum );
+				iFrameBufferTwo->SetStatus( EFull );
+			
+	        if (iFrameBufferOne->Status() == EAvailable ) 
+		        {
+		        iCurrentBuffer = iFrameBufferTwo;   
+		       	iStateMachine->ChangeState( ESourceDataReady );    	
+		        }
+	       	}
+	    else
+	        {
+	        // Neither of the buffers is available and leave
+	        User::Leave( KErrNotReady ); 
+	        }
+    }
+    else
+		{
+		DP_MSRP_WRITE("CMsrpPayloadFormatRead::BufferFilledL IGNORING Packet, data recovered!");
+		}
+		
+    }
+    else
+    {
+    	DP_MSRP_WRITE("CMsrpPayloadFormatRead::BufferFilledL NO PAYLOAD, Data smaller than 8 bytes ");
+    	iStateMachine->ChangeState( EWaitSourceData );
+    }
+    
+    
+}
+
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::DecodePayloadL( const TDesC8& aBuffer )
+//
+// Decodec payload according level 2 redundancy ( RFC 4103 )
+// First there are Normal RTP Header, which was extracted by RTP Stack.
+// Then there are two 32-bit Redundant headers and one 8 -bit primary Header.
+// Then there are R2, R1 and Primary data appended respectively.
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::DecodePayloadL( const TDesC8& aBuffer )
+{	
+		DP_MSRP_WRITE("CMsrpPayloadFormatRead::DecodePayload()");
+		
+		TInt ret = KErrNone;
+		RDebug::Print( _L("CMsrpPayloadFormatRead::DecodePayload() -> %d") , aBuffer.Size() );
+		const TUint8* aPtr = aBuffer.Ptr(); 
+		TInt ctr(0);
+	
+		// get 1st 32 = R2 header
+		TUint32 r2Header = Read32( aPtr );
+		
+		RDebug::Print( _L("CMsrpPayloadFormatRead R2 Header Data : %x"), r2Header );
+		aPtr += 4;
+		ctr+= 4; 
+		TUint16 aR2Lenght(0), aR2TimeStamp(0);
+		TInt err = ParseRedHeader( r2Header, aR2Lenght, aR2TimeStamp );
+		
+	    RDebug::Print( _L("CMsrpPayloadFormatRead R2 Lengt : %d , TimeStamp %x "), aR2Lenght, aR2TimeStamp );
+		if( err )
+		{
+			User::Leave( err );
+		}
+		
+		// get 2nd 32 =  R1 header
+		TUint32 r1Header = Read32( aPtr );
+		RDebug::Print( _L("CMsrpPayloadFormatRead R1 Header Data : %x"), r1Header );
+		aPtr += 4;
+		ctr +=4; 
+		TUint16 aR1Lenght(0), aR1TimeStamp(0);
+		err = ParseRedHeader( r1Header, aR1Lenght, aR1TimeStamp );
+		RDebug::Print( _L("CMsrpPayloadFormatRead R1 Lengt : %x , TimeStamp %x "), aR1Lenght, aR1TimeStamp );
+		if( err )
+		{
+			User::Leave( err );
+		}
+		
+		// get 
+		TUint8 aPt = ( Read8( aPtr ) & 255 ); 
+		aPtr += 1;
+		ctr += 1;
+		TUint8 pPayloadType = ( aPt & 127 ); 
+		TUint8 pBit = ( aPt >> 7 );
+	
+		RDebug::Print( _L("CMsrpPayloadFormatRead Primary data : %d "), aPt );
+		RDebug::Print( _L("CMsrpPayloadFormatRead Primary bit : %d , PT %d "), pBit, pPayloadType );
+		
+		//TODO: When IOP-Tests Are done clean me out.
+		TPtr8 pP = iCharData->Des();
+		pP.FillZ();
+		pP.Zero();
+		pP.Append(aPtr, aR2Lenght); 
+		aPtr += aR2Lenght;
+		TBuf16<KDataSize> unicode;
+	  	User::LeaveIfError(
+	    			CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode, pP ));
+		TStringElement data;
+		data.iData = unicode;
+		iRedData->AppendL(data);
+		
+		RDebug::Print( _L("CMsrpPayloadFormatRead GOT Data %S "), &pP );
+		
+		pP.FillZ();
+		pP.Zero();
+		pP.Append(aPtr, aR1Lenght);
+		aPtr += aR2Lenght;
+		unicode.FillZ();
+		unicode.Zero();
+		User::LeaveIfError(
+	    			CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode, pP ));
+		data.iData = unicode;
+		iRedData->AppendL(data);
+
+		RDebug::Print( _L("CMsrpPayloadFormatRead GOT Data %S "), &pP );
+		TInt rest = aBuffer.Size() - ( ctr + aR2Lenght + aR1Lenght);
+		
+		//NO PRIMARY DATA, means redundant packet 
+		if( rest == 0)
+		{
+			ret = KErrNotFound;	
+		}
+		
+		RDebug::Print( _L("CMsrpPayloadFormatRead Rest %d "), rest );
+		
+		pP.FillZ();
+		pP.Zero();
+		pP.Append(aPtr, rest );
+		aPtr += aBuffer.Size();
+		unicode.FillZ();
+		unicode.Zero();
+		User::LeaveIfError(
+	    			CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode, pP ));
+		data.iData = unicode;
+		iRedData->AppendL(data);
+		
+		RDebug::Print( _L("CMsrpPayloadFormatRead GOT Data %S "), &pP );
+		return ret;
+	
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::ParseRedHeader
+// Small helper method that parses the 32-bit redundant header
+// according to RFC 4103
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::ParseRedHeader(TUint32 /*aHeader*/, TUint16& /*aLenght*/, TUint16& /*aTimeStamp*/ )
+{
+	// Not Supported
+#if 0
+		TUint8 aPt = ( aHeader >> 24 ) & 255;
+		TUint8 aTest = ( aHeader ) & 255;
+		
+		TUint8 aBit = ( aPt >> 7 ) & 1;
+		TUint8 aPayloadType = ( aPt & 127 );
+		//TODO: Checks fi PayloadTypes and bits match
+		
+		aTimeStamp = ( aHeader >> 10 ) & 0x3FFF; 
+		aLenght = ( aHeader & 0x3FF );
+		//TODO: Checks if timestampoffset and lenght is ok
+#endif
+		return KErrNone;
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::HandleRedundancyL
+// Logic method, that updates all counters and decides what data we should
+// append to userBuffer. If packets are missing, we must use redundant data
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::HandleRedundancyL(TInt aErrNo)
+{
+		
+		DP_MSRP_WRITE2("CAnyPayloadFormatRead::BufferFilledL iLevelsMissing: %d", iLevelsMissing );
+		DP_MSRP_WRITE2("CAnyPayloadFormatRead::BufferFilledL iFirstPacketsMissing: %d", iFirstPacketsMissing );
+		DP_MSRP_WRITE2("CMsrpPayloadFormatRead::HandleRedundancy() -> 0 :%S", &iRedData->At(0).iData  );
+		DP_MSRP_WRITE2("CMsrpPayloadFormatRead::HandleRedundancy() -> 1 :%S", &iRedData->At(1).iData  );
+		DP_MSRP_WRITE2("CMsrpPayloadFormatRead::HandleRedundancy() -> 2 :%S", &iRedData->At(2).iData );
+		
+			//if first packet is missing handle all redData
+			if( iFirstPacketsMissing )
+			{	
+	        	iDecodedBuffer->Data().Append( iRedData->At(2).iData );
+	        	iDecodedBuffer->Data().Append( iRedData->At(1).iData );
+	        	iDecodedBuffer->Data().Append( iRedData->At(0).iData );					
+				iSatisfySecNumber += 3;
+			}
+			else // check levels from 
+			{
+				switch(iLevelsMissing)
+				{	
+						case(0):		
+							// expected packet errived
+							iDecodedBuffer->Data().Append(iRedData->At(2).iData);
+							iSatisfySecNumber ++;	
+						break;
+						
+						case(-1): // one packet missing
+							if( aErrNo )
+								{
+								iDecodedBuffer->Data().Append(iRedData->At(2).iData);	
+								}
+							if ( iRedData->At(1).iData.Length() != 0 )
+								{
+								iDecodedBuffer->Data().Append(iRedData->At(1).iData);	
+								}
+							iSatisfySecNumber += 2;
+							iDroppedPacketCount += 1;	
+						break;
+						
+						case(-2): // two packets missing
+							if( aErrNo )
+								{
+								iDecodedBuffer->Data().Append(iRedData->At(2).iData);	
+								}
+							if ( iRedData->At(1).iData.Length() != 0 )
+								{
+								iDecodedBuffer->Data().Append(iRedData->At(1).iData);	
+								}
+							if ( iRedData->At(0).iData.Length() != 0 )
+								{
+								iPayloadBuffer->Data().Append(iRedData->At(0).iData);	
+								}
+							iSatisfySecNumber += 3;
+							iDroppedPacketCount += 2;
+						break;
+						 
+						default:
+							//bacause if network idles or in debugging state
+							// a lot of packets might not be received.
+							//we are handlng all as missing chars
+							DP_MSRP_WRITE("CMsrpPayloadFormatRead::LevelsMissing > 2!");
+						
+							iDecodedBuffer->Data().Append(KLostChar);
+							iSatisfySecNumber += (-iLevelsMissing ) +1;
+							iDroppedPacketCount += (-iLevelsMissing );
+						
+						break;
+				}
+			}		
+	return KErrNone;
+}
+        
+         
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::ResetPacketBuffers()
+// Helper method that that resets all buffers used
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::ResetPacketBuffers()
+	{
+	DP_MSRP_WRITE("CMsrpPayloadFormatRead::ResetPacketBuffers()");
+	iRedData->Reset();
+	iCharData->Des().FillZ();
+	iCharData->Des().Zero();
+	iDecodedBuffer->Data().FillZ();
+	iDecodedBuffer->Data().Zero();
+	}
+
+
+// NOT CALLED, BECAUSE WE ARE USING RTP ONLY
+void CMsrpPayloadFormatRead::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
+	{        
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::BufferFilledL");
+    User::Leave( KErrNotSupported );
+	}
+	
+	
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::Duration
+// Return the clip duration for the given media.
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMsrpPayloadFormatRead::Duration( 
+	TMediaId /*aMediaType*/ ) const
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::Duration");    
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::LastDlPacketCount
+// Return current packet count for current talk spurt
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatRead::LastDlPacketCount( ) 
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::LastDlPacketCount");   
+    return iPacketCount;
+    }
+ 
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CancelDlRequest( )
+// 
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::CancelDlRequest()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::CancelDlRequest");
+  	iStateMachine->Cancel();
+    iStateMachine->ChangeState( EDecodeIdle );
+    
+    if ( iFrameBufferOne && iFrameBufferTwo )
+        {
+        iFrameBufferOne->SetLastBuffer( EFalse );
+        iFrameBufferTwo->SetLastBuffer( EFalse );
+
+        iFrameBufferOne->SetStatus( EAvailable );
+        iFrameBufferTwo->SetStatus( EAvailable );
+        }
+
+    iBufferToReadExists = EFalse;
+    iCurrentBuffer = iFrameBufferOne;
+    iFillRequested = EFalse;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourcePrimeL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SourcePrimeL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourcePrimeL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    iClip->SourcePrimeL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourcePlayL()
+//
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SourcePlayL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourcePlayL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+
+		// init packet count
+    iPacketCount = 0;
+    
+    //init satisfiable sec number count
+    iSatisfySecNumber = 0;
+    
+    iCheckSum = 0;
+    
+    // init levelsMissingNumber
+    iLevelsMissing = 0;
+    
+    //init flag
+    iPacketSecNumber = EFalse;
+    
+    iClip->SourcePlayL();
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourcePauseL()
+//
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SourcePauseL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourcePauseL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    
+    this->CancelDlRequest();
+    iClip->SourcePauseL();
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SourceStopL( )
+//
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::SourceStopL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SourceStopL");
+    __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
+    
+    this->CancelDlRequest();
+    iClip->SourceStopL();
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::SinkDataTypeCode()
+// Returns the datatype code for this Format Decoder
+// -----------------------------------------------------------------------------
+//
+TFourCC CMsrpPayloadFormatRead::SinkDataTypeCode( TMediaId aMediaId )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::SinkDataTypeCode");
+    //TODO: We have to check that media type text
+	
+		if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+			{
+			return iFourCC;
+			}
+		else
+			{
+			return TFourCC(); //defaults to 'NULL' fourCC
+			}
+	
+    }
+   
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::ConfigurePayloadFormatL
+// Configure payload decoding parameters.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatRead::ConfigurePayloadFormatL( 
+	const TDesC8& aConfigParams )
+	
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::ConfigurePayloadFormatL");
+    TMccCodecInfoBuffer infoBuffer;
+    infoBuffer.Copy( aConfigParams );
+    TMccCodecInfo cInfo = infoBuffer();
+    
+    if ( cInfo.iIsUpdate && cInfo.iFrameSize == iCodecInfo.iFrameSize )
+        {
+        //__MsrpFORMAT_CONTROLL( "CMsrpPayloadFormatRead::ConfigurePayloadFormatL, nothing to configure" )
+        return;
+        }
+        
+    UpdateConfigurationL( aConfigParams );
+        
+}
+
+
+void CMsrpPayloadFormatRead::UpdateConfigurationL(const TDesC8& aConfigParams)
+	{
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::UpdateConfigurationL");
+	TMccCodecInfoBuffer infoBuffer;
+    infoBuffer.Copy( aConfigParams );
+    TMccCodecInfo cInfo = infoBuffer();
+	
+	//TODO: get me right 
+   // iCodecInfo = cInfo;
+   //	iCodecInfo.iRedundancyCount = 0;
+   iCodecInfo = cInfo;
+
+    //Create buffers respectively
+  	if ( !iFrameBufferOne )
+	    {
+	    iFrameBufferOne = 
+	    	CMMFDataBuffer::NewL( KRedHeaderSize + KDataSize );
+	    iFrameBufferOne->SetStatus( EAvailable );
+	    }
+	    
+	if ( !iFrameBufferTwo )
+	    {
+	    iFrameBufferTwo =
+	    	CMMFDataBuffer::NewL( KRedHeaderSize + KDataSize );
+	    iFrameBufferTwo->SetStatus( EAvailable );
+	    }
+	    
+	if ( iPayloadBuffer && iSourceBufOwnership ) 	
+	    {
+	    delete iPayloadBuffer;
+	    iPayloadBuffer = NULL;
+	    }
+    
+    iPayloadBuffer 
+        = CreateClipBufferL( KRedHeaderSize + KDataSize, iSourceBufOwnership );
+    
+    iCurrentBuffer = NULL;
+    
+	}
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CreateClipBufferL
+// Creates buffer needed in data transfer with format readers clip.
+// -----------------------------------------------------------------------------
+//
+CMMFDataBuffer* CMsrpPayloadFormatRead::CreateClipBufferL( 
+        TUint aSize, TBool& aIsOwnBuffer )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::CreateClipBufferL");
+    CMMFDataBuffer* buffer( NULL );
+    
+    if ( iClip->CanCreateSourceBuffer() )
+        {
+        static_cast<CMMFFormatDecode*>( iClip )->SuggestSourceBufferSize( aSize );
+        TBool reference( EFalse );
+        
+        //TODO: We have to change media type
+        CMMFBuffer* sourceBuf 
+            = iClip->CreateSourceBufferL( KUidMediaTypeAudio, reference );
+            
+        TBool isSupportedBuf 
+            = CMMFBuffer::IsSupportedDataBuffer( sourceBuf->Type() );
+            
+        TBool isOwnBuffer = reference ? EFalse : ETrue;
+        
+        if ( !isSupportedBuf )
+            {
+            if ( isOwnBuffer )
+                {
+                delete sourceBuf;
+                }
+            
+            User::Leave( KErrNotSupported );
+            }
+        
+        aIsOwnBuffer = isOwnBuffer;
+        buffer = static_cast<CMMFDataBuffer*>( sourceBuf );
+        
+        }
+    else
+        {
+        aIsOwnBuffer = ETrue;
+        buffer = CMMFDataBuffer::NewL( aSize );
+        }
+        
+    
+    return buffer;
+  
+    }
+
+// ==========================    HELPER FUNCTIONS    =========================
+// ========================== 						 =========================
+// ========================== 						 =========================
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::Read32
+// Helper method that reads 32-bit unsigned integer from databuffer
+// -----------------------------------------------------------------------------
+//
+TUint32 CMsrpPayloadFormatRead::Read32( const TUint8* const aPointer )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::Read32");
+    return ( aPointer[3] +
+             ( static_cast<TUint32>( aPointer[2] ) << 8 ) +
+             ( static_cast<TUint32>( aPointer[1] ) << 16 ) +
+             ( static_cast<TUint32>( aPointer[0] ) << 24 ) );
+    } 
+    
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::Read8
+// Helper method that reads 8-bit unsigned integer from databuffer
+// -----------------------------------------------------------------------------
+TUint32 CMsrpPayloadFormatRead::Read8( const TUint8 *const aPointer )
+	{	
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::Read8");
+		
+    return static_cast<TUint32> ( aPointer[0] );
+	}
+	
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::Read24
+// Helper method that reads 24-bit unsigned integer from databuffer
+// -----------------------------------------------------------------------------
+TUint32 CMsrpPayloadFormatRead::Read24( const TUint8 *const aPointer )
+	{
+    DP_MSRP_WRITE("CMsrpPayloadFormatRead::Read24");
+    
+	return ( aPointer[2] + ( static_cast<TUint32>( aPointer[1] ) << 8 ) +
+	       ( static_cast<TUint32>( aPointer[0] ) << 16 ) );
+	}
+	
+	    
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File