multimediacommsengine/mmcesrv/mmcemediamanager/src/mcemediasdpcodec.cpp
changeset 0 1bce908db942
child 14 5bf83dc720b3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcemediasdpcodec.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1615 @@
+/*
+* Copyright (c) 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:    
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include "mcemediadefs.h"
+#include "mcemediasdpcodec.h"
+#include "mcecomcodec.h"
+#include "mcemmlogs.h"
+#include "mcepreconditions.h"
+#include "mcesdpsession.h"
+#include "mcesip.h"
+#include "mcemediamanager.h"
+#include "mcenatpluginmanager.h"
+
+#include <sdpconnectionfield.h>
+#include <sdpdocument.h>
+#include <sdpcodecstringconstants.h>
+#include <sdpcodecstringpool.h>
+#include <sdpmediafield.h>
+#include <sdpattributefield.h>
+#include <sdprtpmapvalue.h>
+#include <sdpfmtattributefield.h>
+#include <sdporiginfield.h>
+#include <sdpbandwidthfield.h>
+#include <mmcccodecinformation.h>
+#include <sdpcodecstringpool.h>
+#include <delimitedpathsegment8.h>
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::CMceMediaSdpCodec
+// -----------------------------------------------------------------------------
+CMceMediaSdpCodec::CMceMediaSdpCodec( RStringF aMedia )
+    : CMceSdpCodec( aMedia )
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::~CMceMediaSdpCodec
+// -----------------------------------------------------------------------------
+CMceMediaSdpCodec::~CMceMediaSdpCodec()
+    {
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodeMediaOfferL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeMediaOfferL( 
+    CMceComMediaStream& aStream, 
+    CSdpMediaField& aMediaLine, 
+    CSdpDocument& aSdpDocument )
+    { 
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeMediaOfferL(), Entry ")
+    
+    // get all the codecs to be offered for this media stream.
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream );
+
+    CMceComCodec* codec = NULL;
+    CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated );
+    
+    // Set the fmt list containing all supported payload 
+    // types supported by this media
+    // i.e. all the rtpmap fields in the pointer array
+    HBufC8* fmtlist = CreateFormatListL( codecs );
+    CleanupStack::PushL( fmtlist ); 
+    codecs.Reset();
+
+    aMediaLine.SetFormatListL( *fmtlist );
+    CleanupStack::PopAndDestroy( fmtlist ); 
+    
+    MCEMM_DEBUG_SVALUE("encoded formatlist", aMediaLine.FormatList() )
+    
+    // For each codec supported by this stream create a rtpmap field
+    // e.g. a=rtpmap: 97 AMR/8000
+    // and ptime and maxptime
+    // e.g. a=ptime:20 a=maxptime:40
+    while( codecs.Next( codec ) )
+        {
+        CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec );
+
+        EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap );
+
+        aMediaLine.FormatAttributeFields().AppendL( rtpmap );
+        CleanupStack::Pop( rtpmap );
+        
+        EncodeFmtpAttributeL( *codec, aMediaLine );
+        
+        }  
+    
+    //encode direction
+    EncodeDirectionL( aStream, aMediaLine, aSdpDocument, EMceRoleOfferer );
+    
+    //encode client attributes if any
+    EncodeClientAttributesL( aStream, aMediaLine );
+        
+    //encode secure session if any
+    EncodeSecureSessionL( aStream, aMediaLine, EMceRoleOfferer );
+    
+    //encode preconditions if any
+    EncodePreconditionsL( aStream, aMediaLine, EMceRoleOfferer );
+    
+    //encode rtcp port 
+    EncodelocalRtcpAttrL( aMediaLine, aStream );
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeMediaOfferL(), Exit ")
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeMediaAnswerL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode CMceMediaSdpCodec::DecodeMediaAnswerL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream,
+    CSdpDocument& aSdpDocument )
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaAnswerL(), Entry ")
+    
+    //should have secure session created
+
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream );
+    CMceComCodec::TIterator codecs( allCodecs );
+    
+    //decode direction or old school hold if necessary                                            
+    DecodeDirectionL( aMediaLine, aStream, aSdpDocument, EMceRoleOfferer );
+	        
+    __ASSERT_ALWAYS( codecs.Count() > 0, User::Leave( KErrNotReady ) );
+    __ASSERT_ALWAYS( aMediaLine.Port() != 0 , User::Leave( KErrNotReady ) );
+
+    //decode based on rtpmaps + their media attributes
+    TInt decoded = DecodePayloadsL( aMediaLine, aStream, EMceRoleOfferer );
+
+    if ( !decoded )
+        {
+        MCEMM_DEBUG("ERROR: No codecs decoded")
+        User::Leave( KErrNotReady );
+        }
+
+	 // check if remote RTCP port is set according to RFC 3605
+    DecodeRemoteRtcpFieldL( aMediaLine, aStream );
+    aStream.SetRemoteMediaPort( aMediaLine.Port() );
+
+    MCEMM_DEBUG_DVALUE("decoded remote port", aStream.RemoteMediaPort() )
+    //decode based on fmtps
+    DecodeFmtpLinesL( aMediaLine, codecs, EMceRoleOfferer );
+
+	 //decode secure session if any
+    DecodeSecureSessionL( aMediaLine, aStream, EMceRoleOfferer );
+    
+    //decode preconditions if any
+    TMceSipWarningCode warnings = 
+        DecodePreconditionsL( aMediaLine, aStream, EMceRoleOfferer );
+    
+    //decode client attributes if any
+    DecodeClientAttributesL( aMediaLine, aStream );
+
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaAnswerL(), Exit ")
+    return warnings;
+    }    
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeMediaOfferL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode CMceMediaSdpCodec::DecodeMediaOfferL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream*& aStream,
+    CMceComSession& aSession,
+    CSdpDocument& aSdpDocument )
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaOfferL(), Entry ")
+    
+    TMceSipWarningCode warning = ValidateSdpL( aMediaLine, aSdpDocument );
+    if ( warning != KErrNone )
+        {
+        return warning;
+        }
+    
+    TInt type = Type( aMediaLine, aSdpDocument.AttributeFields() );
+
+    // create server stream based on the media direction 
+    // attribute (sendonly, sendrcv, rcvonly)
+    aStream = CreateStreamLC( type );
+    aStream->InitializeL( aSession );
+    	
+    //decode direction or old school hold if necessary                                            
+    DecodeDirectionL( aMediaLine, *aStream, aSdpDocument, EMceRoleAnswerer );
+    	
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( *aStream );
+    CMceComCodec::TIterator codecs( allCodecs );
+    
+    //decode based on rtpmaps + their media attributes
+    TInt decoded = DecodePayloadsL( aMediaLine, *aStream, EMceRoleAnswerer );
+    
+    if ( decoded )
+        {
+
+        // check if remote RTCP port is set according to RFC 3605
+        DecodeRemoteRtcpFieldL( aMediaLine, *aStream );
+        aStream->SetRemoteMediaPort( aMediaLine.Port() );
+
+        MCEMM_DEBUG_DVALUE("decoded remote port", aStream->RemoteMediaPort() )
+        
+        //decode based on fmtps
+        DecodeFmtpLinesL( aMediaLine, codecs, EMceRoleAnswerer );
+        
+        //decode session level media attributes        
+        DecodeSessionMediaAttributesL( *aStream, aSdpDocument );
+        
+        
+        //decode secure session if any
+       	DecodeSecureSessionL( aMediaLine, *aStream, EMceRoleAnswerer );
+       	//decode preconditions if any
+        warning = DecodePreconditionsL( aMediaLine, *aStream, EMceRoleAnswerer );
+	
+		    
+        //Decode client attributes if any
+        DecodeClientAttributesL( aMediaLine, *aStream );
+		
+        aSession.Streams().AppendL( aStream );
+        CleanupStack::Pop( aStream );
+        
+        }
+    else
+        {
+        MCEMM_DEBUG("No acceptable codecs found for current media line ")
+            
+        // we did not find any acceptable codecs for this stream, return warning
+        
+        CleanupStack::PopAndDestroy( aStream );
+        aStream = NULL;
+        warning = KMceSipWarnIncompatibleMediaFormat;
+        }
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaOfferL(), Exit ")
+    
+    return warning;
+    
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeMediaUpdateL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode CMceMediaSdpCodec::DecodeMediaUpdateL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream,
+    CSdpDocument& aSdpDocument )
+    {
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaUpdateL(), Entry ")
+    
+    TMceSipWarningCode warning = ValidateSdpL( aMediaLine, aSdpDocument );
+    if ( warning != KErrNone )
+        {
+        return warning;
+        }
+
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream );
+    CMceComCodec::TIterator codecs( allCodecs );
+    
+    aStream.SetRemoteMediaPort( aMediaLine.Port() );
+    MCEMM_DEBUG_DVALUE("decoded remote port", aStream.RemoteMediaPort() )
+    
+    //should have secure media session existed
+    
+    //decode based on rtpmaps + their media attributes
+    TInt decoded = DecodePayloadsL( aMediaLine, aStream, EMceRoleAnswerer );
+    
+    if ( decoded )
+        {
+        // check if remote RTCP port is set according to RFC 3605
+        DecodeRemoteRtcpFieldL( aMediaLine, aStream );
+        
+
+        //decode based on fmtps
+        DecodeFmtpLinesL( aMediaLine, codecs, EMceRoleAnswerer );
+
+        //decode direction or old school hold if necessary                                            
+        UpdateDirectionL( aMediaLine, aStream, aSdpDocument );
+
+        //decode secure session if any
+       	DecodeSecureSessionL( aMediaLine, aStream, EMceRoleAnswerer, KMceMediaCodecUpdate );
+
+
+		//decode preconditions if any
+        warning = DecodePreconditionsL( aMediaLine, aStream, EMceRoleAnswerer );
+        
+        //decode client attributes if any
+        DecodeClientAttributesL( aMediaLine, aStream );
+    
+	    }
+    else
+        {
+        MCEMM_DEBUG("ERROR: No codecs decoded")
+        warning = KMceSipWarnIncompatibleMediaFormat;
+        }
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeMediaUpdateL(), Exit ")
+    return warning;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::EncodeMediaAnswerL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeMediaAnswerL( 
+    CMceComMediaStream& aStream,
+    CSdpMediaField& aMediaLine,
+    CSdpDocument& aSdpDocument )
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeMediaAnswerL(), Entry ")
+    
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream );  
+    CMceComCodec* codec = NULL;
+    CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated );
+
+    if ( codecs.Count() > 0 ) 
+        {
+        
+        // Set the fmt list containing all supported payload 
+        // types supported by this media
+        // i.e. all the rtpmap fields in the pointer array
+        HBufC8* fmtlist = CreateFormatListL( codecs );
+        CleanupStack::PushL( fmtlist ); 
+        codecs.Reset();
+
+        aMediaLine.SetFormatListL( *fmtlist );
+        CleanupStack::PopAndDestroy( fmtlist ); 
+        
+        MCEMM_DEBUG_SVALUE("encoded formatlist", aMediaLine.FormatList() )
+        
+        aMediaLine.SetPortL( aStream.iLocalMediaPort );
+        MCEMM_DEBUG_DVALUE("encoded local port", aMediaLine.Port() )
+        
+        // add the direction attribute
+        EncodeDirectionL( aStream, aMediaLine, aSdpDocument, EMceRoleAnswerer );
+
+        while( codecs.Next( codec ) )
+            {
+            CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec );
+
+            EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap );
+
+            aMediaLine.FormatAttributeFields().AppendL( rtpmap );
+            CleanupStack::Pop( rtpmap );
+            
+            EncodeFmtpAttributeL( *codec, aMediaLine );
+            
+            }
+
+        //encode secure session if any
+        EncodeSecureSessionL( aStream, aMediaLine, EMceRoleAnswerer );
+        
+        //encode preconditions if any
+        EncodePreconditionsL( aStream, aMediaLine, EMceRoleAnswerer );
+        
+        }
+    else
+        { // there was no selected codec for this stream
+        MCEMM_DEBUG("ERROR: No selected codec found! Reject ")
+        aMediaLine.RejectMedia();
+        }
+        
+    // encode client attributes
+    EncodeClientAttributesL( aStream, aMediaLine );
+
+	// encode rtcp attributes
+	EncodelocalRtcpAttrL( aMediaLine, aStream );
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeMediaAnswerL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::TypeL
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::Type( 
+    CSdpMediaField& aMedia, 
+    RPointerArray<CSdpAttributeField>& aSessionAttributes ) const
+    {
+    TInt type = Direction( aMedia, aSessionAttributes );
+    type = type == KErrNotFound ? SdpCodecStringConstants::EAttributeSendrecv : type; 
+    return type;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::PrepareForDecodeL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::PrepareForDecodeL( 
+    CSdpMediaField& /*aMediaLine*/,
+    CMceComMediaStream* aStream )
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::PrepareForDecodeL(), Entry ")
+    
+    if ( aStream )
+        {
+        const RPointerArray<CMceComCodec>& allCodecs = CodecsL( *aStream );
+        CMceComCodec* codec = NULL;
+        CMceComCodec::TIterator codecs( allCodecs );
+        while( codecs.Next( codec ) )
+            {
+            codec->iIsNegotiated = EFalse;
+            }
+        }
+        
+    MCEMM_DEBUG("CMceMediaSdpCodec::PrepareForDecodeL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeRtpmapLinesL
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::DecodeRtpmapLinesL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream,
+    TMceNegotiationRole aRole ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeRtpmapLinesL(), Entry ")
+    TInt decoded = 0;
+	
+    const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream );
+    CMceComCodec* codec = NULL;
+    CMceComCodec::TIterator codecs( allCodecs );
+    
+    RArray<TUint> payloadTypesInMediaLine;
+    CleanupClosePushL( payloadTypesInMediaLine );
+   
+    User::LeaveIfError( DecodeFormatList( aMediaLine, payloadTypesInMediaLine ) );
+ 
+    RPointerArray< CSdpFmtAttributeField >& formatLines =  
+                                            aMediaLine.FormatAttributeFields();
+    
+	for ( TInt i = 0; i < formatLines.Count(); i++ )
+		{
+		CSdpFmtAttributeField* formatLine = formatLines[ i ];
+        if ( formatLine->Attribute() == 
+                    SDP_STRING( SdpCodecStringConstants::EAttributeRtpmap ) )
+            //codec
+            {
+            TPtrC8 fmtpVal = GetCorrespondingFmtpLineL( aMediaLine, *formatLine );
+            
+            MCE_ITERATOR_FIND_NEXT( 
+                codecs, codec, 
+                codec->Decodes( formatLine->Value(), fmtpVal ) );
+                
+            codecs.Reset();
+            
+            if ( !codec && aRole == EMceRoleOfferer )
+                {
+                // No exact match, do less strict matching for better interoperability
+                MCE_ITERATOR_FIND_NEXT( 
+                codecs, codec, 
+                codec->Decodes( formatLine->Value(), fmtpVal, EFalse ) );
+                codecs.Reset();
+                }
+                
+            if ( codec )
+                {
+                MCEMM_DEBUG_SVALUE("decoding codec", codec->iSdpName )
+                
+                const TDesC8& payloadTypeInRtpMap = formatLine->Format();
+                TUint rtpMapPT = ConvertDesToUintL( payloadTypeInRtpMap );
+                
+                TInt val = payloadTypesInMediaLine.Find( rtpMapPT );
+                if ( val != KErrNotFound )
+                    {
+                    TUint payload = ConvertDesToUintL( formatLine->Format() );
+                    if ( !IsPayloadTypeSupported( codec->iSdpName, payload ) ) 
+                    	{
+						// not supported payload, ignore this codec
+                    	continue;
+                    	}
+                    if ( !codec->iIsNegotiated )
+                        {
+                        codec->iPayloadType = payload;
+                        }
+                    codec->iIsNegotiated = ETrue;   
+                    //decode media attributes
+                    DecodeMediaAttributesL( aMediaLine, *codec, *formatLine );
+                    decoded++;
+                    }
+                else
+                    {
+                    // Discarding as there was no matching pt in medialine for
+                    // this rtmpmap line
+                    codec->iIsNegotiated = EFalse;
+                    if ( aStream.BoundStream() )
+                        {
+                        CMceComCodec* sync = NULL;
+                        sync = aStream.BoundStreamL().FindCodecL( *codec );
+                        if ( sync )
+                            {
+                            sync->iIsNegotiated = EFalse; 
+                            }
+                        }
+                    }
+                }
+            else if ( aRole == EMceRoleAnswerer )
+                {
+                if ( DecodeRtpmapLineL( *formatLine, aMediaLine, aStream, fmtpVal ) )
+                    {
+                    decoded++;
+                    }
+                }
+            else
+                {
+                // NOP
+                }
+                    
+            }
+		}
+
+    CleanupStack::PopAndDestroy( &payloadTypesInMediaLine );
+        
+    MCEMM_DEBUG_DVALUE("decoded codecs", decoded )
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeRtpmapLinesL(), Exit ")
+    return decoded;	
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeRtpmapLinesL
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::DecodeRtpmapLinesL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeRtpmapLinesL(), Entry ")
+    TInt decoded = 0;
+
+     // Read format level attributes
+    RPointerArray< CSdpFmtAttributeField >& formatLines =  
+                                            aMediaLine.FormatAttributeFields();
+    
+    // For all codec specific lines in the offer        
+    for ( TInt i = 0; i < formatLines.Count(); i++ )
+        {
+        CSdpFmtAttributeField* formatLine = formatLines[i];
+        if ( formatLine->Attribute() == SDP_STRING( SdpCodecStringConstants::EAttributeRtpmap ) &&
+             DecodeRtpmapLineL( *formatLine, aMediaLine, aStream ) )
+            {
+            decoded++;
+            }
+        }
+
+    MCEMM_DEBUG_DVALUE("decoded codecs", decoded )
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeRtpmapLinesL(), Exit ")
+    return decoded;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeStaticPayloadsL
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::DecodeStaticPayloadsL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream,
+    RArray<TUint>& aPayloadTypes,
+    TMceNegotiationRole aRole ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeStaticPayloadsL(), Entry ")
+    TInt decoded = 0;
+
+    DecodeFormatListL( aMediaLine, aPayloadTypes );
+    TInt index = 0;
+    
+    while( index < aPayloadTypes.Count() )
+        {
+        TUint payload = aPayloadTypes[ index++ ];
+        if ( payload < KMinDynamicPT )
+            {
+            CMceComCodec* codec = FindCodec( payload, aStream );
+            if ( aRole == EMceRoleAnswerer )
+                {
+                if ( !codec )
+                    {
+                    codec = CreateCodecLC( payload, aMediaLine );
+                    if ( codec )
+                        {
+                        codec->InitializeL( aStream );
+                        codec->iIsNegotiated = ETrue;
+                        MCEMM_DEBUG_SVALUE("adding codec", codec->iSdpName )
+                        aStream.AddCodecL( codec );
+                        CleanupStack::Pop( codec );
+                        decoded++;
+                        }
+                    }
+                else
+                    {
+                    codec->iIsNegotiated = ETrue;
+                    decoded++;
+                    }
+                }
+            else if ( codec && aRole == EMceRoleOfferer )
+                {
+                codec->iIsNegotiated = ETrue;
+                decoded++;
+                }
+            }
+        }
+        
+    MCEMM_DEBUG_DVALUE("decoded codecs", decoded )
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeStaticPayloadsL(), Exit ")
+    return decoded;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::FindCodec
+// -----------------------------------------------------------------------------
+//
+CMceComCodec* CMceMediaSdpCodec::FindCodec( 
+    TInt aPayloadType, 
+    CMceComMediaStream& aStream ) const
+    {
+    TInt error = KErrNone;
+    
+    RPointerArray< CMceComCodec > allCodecs;
+    
+    TRAP( error, allCodecs = CodecsL( aStream ) );  
+    CMceComCodec* codec = NULL;
+    if( error == KErrNone )
+    	{
+    	CMceComCodec::TIterator codecs( allCodecs );
+    
+    	MCE_ITERATOR_FIND_NEXT( codecs, codec, codec->iPayloadType == aPayloadType );	
+    	}
+
+    return codec;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeRtpmapLineL
+// -----------------------------------------------------------------------------
+//
+CMceComCodec* CMceMediaSdpCodec::DecodeRtpmapLineL( 
+    CSdpFmtAttributeField& aRtpMaptLine,
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream,
+    const TDesC8& aFmtpValue ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLineL(), Entry ")
+    
+    RArray<TUint> payloadTypesInMediaLine;
+    CleanupClosePushL( payloadTypesInMediaLine );
+   
+    User::LeaveIfError( DecodeFormatList( aMediaLine, payloadTypesInMediaLine ) );
+    	
+    const TDesC8& payloadTypeInRtpMap = aRtpMaptLine.Format();
+    
+    TUint rtpMapPT = ConvertDesToUintL( payloadTypeInRtpMap );
+    CMceComCodec* codec = NULL;
+    
+    // Ingoring if there is no matching pt in medialine for this rtmpmap line
+    if ( payloadTypesInMediaLine.Find( rtpMapPT ) != KErrNotFound )
+        {
+        codec = CreateCodecLC( aRtpMaptLine );
+        if ( codec )
+            {
+            codec->InitializeL( aStream );
+            if ( !codec->SetFmtpProposalL( aFmtpValue ) )
+                {
+                // Fmtp not valid, ignore codec
+                CleanupStack::PopAndDestroy( codec );
+                codec = NULL;
+                }
+            else
+                {
+                // check if ptime or maxptime attributes are present
+                DecodeMediaAttributesL( aMediaLine, *codec, aRtpMaptLine );
+                codec->iIsNegotiated = ETrue;
+                MCEMM_DEBUG_SVALUE("adding codec", codec->iSdpName )
+                aStream.AddCodecL( codec );
+                CleanupStack::Pop( codec );
+                }
+            }    
+        }
+
+    CleanupStack::PopAndDestroy( &payloadTypesInMediaLine );
+
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLineL(), Exit ")
+    return codec;        
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeFmtpLinesL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeFmtpLinesL( 
+    CSdpMediaField& aMediaLine,
+    CMceComCodec::TIterator& aCodecs,
+    TMceNegotiationRole aRole ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLinesL(), Entry ")
+
+    RPointerArray< CSdpFmtAttributeField >& formatLines =  
+        aMediaLine.FormatAttributeFields();
+    
+    CMceComCodec* codec = NULL;
+    while( aCodecs.Next( codec ) )
+        {
+   	    TBool first = ETrue;
+        // for all codec specific lines in the offer
+        TBool found = EFalse;
+    	for ( TInt j = 0; j < formatLines.Count(); j++ )
+    		{
+    		CSdpFmtAttributeField* formatLine = formatLines[ j ];
+    		if ( formatLine->Attribute() == 
+    		            SDP_STRING( SdpCodecStringConstants::EAttributeFmtp ) )
+    			{
+    			TUint payloadType = ConvertDesToUintL( formatLine->Format() );
+				if ( codec->iPayloadType == payloadType )
+				    {
+                    MCEMM_DEBUG_SVALUE("decoding format", formatLine->Format() )
+					const TDesC8& fmtpValue = formatLine->Value();
+                    MCEMM_DEBUG_SVALUE("decoding fmtp", fmtpValue )
+                    found = ETrue;
+                    TBool isAnswerer( aRole == EMceRoleAnswerer );
+					if ( first )
+					    {
+					    codec->SetFmtpFromIncomingSdpL( 
+					                fmtpValue, isAnswerer, KMceCodecFmtpReset );
+					    first = EFalse;
+					    }
+                    else
+                        {
+        				codec->SetFmtpFromIncomingSdpL( 
+        				            fmtpValue, isAnswerer, KMceCodecFmtpAppend );
+                        }
+				    }
+    			}
+    		}
+    	if ( !found )
+        	{
+            // No fmtp line found, use default values
+            codec->SetDefaultFmtpAttributeL();
+            }
+        MCEMM_DEBUG_SVALUE("decoded fmtp", *codec->iFmtpAttr )         
+        }
+   	    
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLinesL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodeFmtpAttributeL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeFmtpAttributeL( 
+    CMceComCodec& aCodec,
+    CSdpMediaField& aMedia ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeFmtpAttributeL(), Entry ")
+    
+    RStringF attributeFmtp = 
+        SDP_STRING( SdpCodecStringConstants::EAttributeFmtp );
+    
+    if( aCodec.iFmtpAttr && aCodec.iFmtpAttr->Size() != 0 )
+        {
+        MCE_DEFINE_DECSTR( payload, aCodec.iPayloadType )
+
+        HBufC8* fmtpAttr = aCodec.FtmpForOutgoingSdpLC();
+        CSdpFmtAttributeField* fmtpLine = 
+            CSdpFmtAttributeField::NewL( attributeFmtp, payload, *fmtpAttr );
+        CleanupStack::PopAndDestroy( fmtpAttr );
+        CleanupStack::PushL( fmtpLine );                         
+        aMedia.FormatAttributeFields().AppendL( fmtpLine );
+        CleanupStack::Pop( fmtpLine );
+        
+        MCEMM_DEBUG_SVALUE( "encoded fmtp", fmtpLine->Value() )
+        }
+        
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeFmtpAttributeL(), Exit ")
+    }
+        
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::CreateFormatListL
+// Creates fmtlist that can be used as media field fmt list -attribute
+// (other items were commented in a header).
+// Status : Draft 
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMceMediaSdpCodec::CreateFormatListL( 
+    CMceComCodec::TIterator& aCodecs ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::CreateFmtListL(), Entry ")
+    
+    HBufC8* fmtList = HBufC8::NewLC( KMceSdpFormatListLength );
+    TPtr8 fmtListPtr( fmtList->Des() );
+
+    CMceComCodec* codec = NULL;
+    for ( TInt count = 0; count <= aCodecs.Count()-1; count++ )
+    	{
+    	aCodecs.Next( codec );
+    	MCE_DEFINE_DECSTR( payload, codec->iPayloadType )
+    	fmtListPtr.Append( payload );
+       	if ( count != aCodecs.Count()-1)
+       		{
+       		fmtListPtr.Append( KMceSipBlank );
+       		}
+    	}
+    
+    CleanupStack::Pop( fmtList );
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::CreateFmtListL(), Exit ")
+    
+    return fmtList;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeFormatListL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeFormatListL( 
+    CSdpMediaField& aMedia, 
+    RArray<TUint>& aPayloadTypes ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFormatListL(), Entry ")
+    
+    User::LeaveIfError( DecodeFormatList( aMedia, aPayloadTypes ) );
+        
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFormatListL(), Exit ")   
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeFormatList
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::DecodeFormatList( 
+    CSdpMediaField& aMedia, 
+    RArray<TUint>& aPayloadTypes ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFormatList(), Entry ")
+    
+    TInt index = 0;
+    const TDesC8& payloadlist = aMedia.FormatList();
+    MCEMM_DEBUG_SVALUE( "decoded format list", payloadlist )
+    TLex8 payloads( payloadlist );
+    TInt error = KErrNone;
+    
+    while( error == KErrNone && !payloads.Eos() && index < KMceMaxPayloadTypes )
+        {
+        TPtrC8 payload = payloads.NextToken();
+        TUint convertedUnit = 0;
+        TLex8 lexConv( payload );
+        TInt err = lexConv.Val( convertedUnit, EDecimal );
+        if( err != KErrNone )
+        	{
+        	error = err;
+        	break;
+        	}
+        error = aPayloadTypes.Append( convertedUnit );
+        index++;
+        }
+
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFormatList(), Exit ")
+    
+    return error;
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeRemoteRtcpFieldL
+//
+// a=rtcp:53020 IN IP4 126.16.64.4
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeRemoteRtcpFieldL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream ) const
+    {   
+    MCEMM_DEBUG( "CMceMediaSdpCodec::ParseRemoteRtcpFieldL(), Entry" )
+
+    RStringF rtcpAttributeName = iStringPool.OpenFStringL( KMceSdpAttrRtcp );
+    CleanupClosePushL( rtcpAttributeName );
+    _LIT8( KMatchIN,"*IN*" );       
+    _LIT8( KMatchIp,"*IP*" );
+    
+    RPointerArray<CSdpAttributeField>& attrfields = 
+        aMediaLine.AttributeFields();
+    
+    for ( TInt i = 0; i < attrfields.Count(); i++ )
+        {
+        CSdpAttributeField* attribute = attrfields[i];        
+        if ( attribute->Attribute() == rtcpAttributeName ) 
+            {
+            const TDesC8& value = attribute->Value();
+            TUint rtcpPort( 0 );
+            
+            if ( value.Match( KMatchIN ) != KErrNotFound )
+                {
+                // found remote IP4 RTCP address
+                const TUint8 KAddrOffsetFromNetType = 4;
+                TInt addr_offset = 
+                    value.Match( KMatchIp ) + KAddrOffsetFromNetType;
+                TPtrC8 remoteRtcpAddr = value.Mid( addr_offset );
+                
+                const TUint8 KPortOffsetFromIP = 1;
+                TInt port_offset = 
+                    value.Match( KMatchIN ) - KPortOffsetFromIP;
+                TPtrC8 remoteRtcpPort = value.Left( port_offset );
+                
+                TLex8 lexPT( remoteRtcpPort );
+                User::LeaveIfError( lexPT.Val( rtcpPort, EDecimal ) );
+                // copy the address into correct format
+                TBuf16 <KMaxAddressLength> input;
+                input.Copy( remoteRtcpAddr );      
+                
+                MCEMM_DEBUG_SVALUE( "Found RTCP address", input )
+                
+                aStream.SetRemoteRtcpMediaAddrL( input );
+                }
+            else
+                {
+                // only port present
+                TLex8 lexPT( value );
+                User::LeaveIfError ( lexPT.Val( rtcpPort, EDecimal ) );
+                }
+
+			aStream.SetRemoteRtcpMediaPort( rtcpPort );
+            
+            MCEMM_DEBUG_DVALUE( "RTCP Port", rtcpPort )
+            }
+        }
+    
+    CleanupStack::PopAndDestroy( &rtcpAttributeName );
+      
+    MCEMM_DEBUG( "CMceMediaSdpCodec::ParseRemoteRtcpFieldL(), Exit" )    
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodelocalRtcpAttrL
+//
+// a=rtcp:53020 IN IP4 126.16.64.4
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodelocalRtcpAttrL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream ) const
+    {   
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodelocalRtcpAttrL, Entry ")
+    if ( aStream.Session() && aStream.Session()->UseRtcp() )
+		{
+		MCEMM_DEBUG("RTCP attribute to be added")
+    	TBuf8<KMceSdpMaxMediaLineLength> rtcpAttrValue;
+		rtcpAttrValue.Num( aStream.iLocalMediaPort + 1, EDecimal );
+		 if ( !aStream.Session()->iLocalIpAddress.IsUnspecified() )
+			{
+			CSdpConnectionField* connectionField = 
+			    CSdpConnectionField::NewL( aStream.Session()->iLocalIpAddress );
+			CleanupStack::PushL( connectionField );
+			rtcpAttrValue.Append( KMceSdpSpace );   
+		    rtcpAttrValue.Append( connectionField->NetType().DesC() );  
+		    rtcpAttrValue.Append( KMceSdpSpace );        
+		 	rtcpAttrValue.Append( connectionField->AddressType().DesC() );
+		 	rtcpAttrValue.Append( KMceSdpSpace );      
+		 	rtcpAttrValue.Append( connectionField->Address() );
+		 	CleanupStack::PopAndDestroy( connectionField );
+			}
+		RStringF attributeRtcp = 
+            SdpCodecStringPool::StringPoolL().OpenFStringL( KMceSdpAttrRtcp );
+		CleanupClosePushL( attributeRtcp );
+
+		CSdpAttributeField* rtcpLine = 
+		            CSdpAttributeField::NewLC( attributeRtcp, rtcpAttrValue );
+		        
+		MCEMM_DEBUG_SVALUE("encoded rtcpPort", aStream.iLocalMediaPort + 1 )
+
+		aMediaLine.AttributeFields().AppendL( rtcpLine );
+
+		CleanupStack::Pop( rtcpLine ); 
+		CleanupStack::PopAndDestroy( ); //attributeRtcp 
+		}
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodelocalRtcpAttrL, Exit ")    
+    }    
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::CleanAttributes
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::CleanAttributes( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::CleanAttributes(), Entry ")
+    
+    //clean attributes
+    aMedia.AttributeFields().ResetAndDestroy();
+        
+    //clean format attributes
+    aMedia.FormatAttributeFields().ResetAndDestroy();
+       
+    aMedia.BandwidthFields().ResetAndDestroy();
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::CleanAttributes(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeSecureSessionL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeSecureSessionL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream, 
+    TMceNegotiationRole aRole,
+    TBool aUpdate )
+    {
+    
+    CMceSecureMediaSession* secureSession = aStream.Session()->SecureSession();
+
+    if ( aRole == EMceRoleAnswerer && !aUpdate )
+        {
+        aStream.Session()->SecureSessionL().DecodeSecureDesSdpOfferL( aStream, aMediaLine );
+        if ( !aStream.Session()->iIsSecureSession )
+            {
+            aStream.Session()->DeleteSecureSession();
+            }
+        }
+    else if ( secureSession && aRole == EMceRoleAnswerer && aUpdate )
+        {
+        // for long session
+        if ( secureSession->iKeyNeedUpdated )
+        	{
+        	secureSession->DecodeSecureDesSdpUpdateL( aStream, aMediaLine ) ;
+        	}
+        }
+    else if ( secureSession && aRole == EMceRoleOfferer )
+        {
+       	// for Long Session
+        	//sendonly receive only sendandreceive
+     	secureSession->DecodeSecureDesSdpAnswerL( aStream, aMediaLine ) ;
+       	}        
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodeSecureSessionL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeSecureSessionL( 
+    CMceComMediaStream& aStream, 
+    CSdpMediaField& aMediaLine,
+    TMceNegotiationRole aRole )
+    {
+    CMceSecureMediaSession* secureSession = aStream.Session()->SecureSession();
+
+    if ( secureSession )
+        {
+        if ( aRole == EMceRoleOfferer )
+            {
+            secureSession->EncodeSecureDesSdpOfferL( aStream, aMediaLine );
+            }
+        else
+            {
+            secureSession->EncodeSecureDesSdpAnswerL( aStream, aMediaLine );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeDirectionL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeDirectionL( CSdpMediaField& aMediaLine,
+                                          CMceComMediaStream& aStream,
+                                          CSdpDocument& aSdpDocument,
+                                          TMceNegotiationRole aRole ) const
+	{
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeDirectionL(), Entry ")
+
+    TInt rmt_direction = 
+        Direction( aMediaLine, aSdpDocument.AttributeFields() );
+    TInt loc_direction = aStream.Direction();
+    
+    CSdpConnectionField* connectionField = aSdpDocument.ConnectionField();
+    
+    CMceSdpSession& sSession = aStream.Session()->SdpSession();
+        
+    CSdpConnectionField* nullAddress =
+        CSdpConnectionField::DecodeL( KMceSipNullAddressA );
+    				 
+    CleanupStack::PushL( nullAddress );
+
+    TUint oldSchool = sSession.iOOldSchool;
+    TBool isNullAddress = EFalse;
+    if ( connectionField )
+        {
+        isNullAddress = (connectionField->Address() == nullAddress->Address());
+        }
+
+    CleanupStack::PopAndDestroy( nullAddress );
+
+    //trying to guess other party direction if have got no direction
+    if ( rmt_direction == KErrNotFound || 
+         ( rmt_direction == SdpCodecStringConstants::EAttributeSendonly && 
+           loc_direction == SdpCodecStringConstants::EAttributeSendonly ) )
+    
+	    {
+	    if ( aRole == EMceRoleOfferer )
+	      	{
+	   		// did we try old school hold?
+	    	if ( oldSchool )           
+	      	    {
+	      	    if ( !isNullAddress )
+	      	      	{
+	      	  		// ignore that other party didn't understand us
+	      	        // and full cancel of old school process
+	         	    sSession.iOOldSchool = 0;
+	            	sSession.iOOldSchoolProceeding = 0;
+	                sSession.iOOldSchoolCompleted = 0;
+	      	      	}
+	       		
+	       		rmt_direction = SdpCodecStringConstants::EAttributeRecvonly;
+	       		oldSchool = 0;
+	      	    }    
+            else  //  didn't try old school yet
+                {
+                if ( isNullAddress )
+                    {
+                    // assuming that other party wanna put us on hold
+	                rmt_direction = SdpCodecStringConstants::EAttributeSendonly; 
+                    }
+	            else if ( loc_direction == 
+	                          SdpCodecStringConstants::EAttributeSendonly &&
+	               		  aStream.Session()->Modifier( KMceMediaDirection ) ==
+	              			  KMceMediaDirectionWithAddress )
+                    {
+                    // failed to put other party on hold, trying old school
+                    sSession.iOOldSchool = 1;    
+                    User::Leave( KMceErrOldSchool );
+                    }
+                else
+                    {
+                    // NOP
+                    }
+                }
+	      	}
+        else // answerer
+            {
+            if ( isNullAddress )
+                {
+                // other party puts us on hold
+                rmt_direction = SdpCodecStringConstants::EAttributeSendonly;
+                sSession.iIOldSchool = 1;
+                oldSchool = sSession.iIOldSchool;
+                }
+	        else
+	            {
+	            rmt_direction = SdpCodecStringConstants::EAttributeSendrecv;
+	            }   	
+            }
+	    }
+
+    sSession.iIOldSchool = oldSchool;
+
+	// if unable to determine other party direction then just ignore that
+    if ( rmt_direction != KErrNotFound )
+        {
+    	// now checking for permitted directions
+    	// inverse direction
+        TInt inv_dir = rmt_direction;
+        switch (inv_dir)
+        	{
+          	case SdpCodecStringConstants::EAttributeRecvonly: 
+          		{
+          		inv_dir=SdpCodecStringConstants::EAttributeSendonly; 
+          		break;		
+          		}      
+          	case SdpCodecStringConstants::EAttributeSendonly: 
+          		{
+          		inv_dir=SdpCodecStringConstants::EAttributeRecvonly; 
+          		break;		
+          		}
+          	default:
+          		{
+          		break;		
+          		}
+        	}
+
+		// all directions are permitted for answerer and 
+		// inactive is always accepted
+    	if ( aRole == EMceRoleOfferer && 
+    	     rmt_direction != SdpCodecStringConstants::EAttributeInactive )
+    		{
+    		// other party has incompatible direction. terminate session.
+           	if ( loc_direction != SdpCodecStringConstants::EAttributeSendrecv 
+           	     && 
+           	     loc_direction != inv_dir )
+           	    {
+           	    User::Leave( KErrArgument );
+           	    }
+    		}
+
+    	if ( loc_direction != inv_dir )
+    	    {
+    	    aStream.SetDirection( rmt_direction, KMceNoEndpointAdjustment );
+    	    }
+    	}
+
+    MCEMM_DEBUG_SVALUE("decoded direction", 
+    					SDP_STRING( aStream.Direction() ).DesC() )
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeDirectionL(), Exit ")
+ 	}
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::UpdateDirectionL
+// -----------------------------------------------------------------------------
+//
+    
+void CMceMediaSdpCodec::UpdateDirectionL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream,
+    CSdpDocument& aSdpDocument ) const
+	{
+    TInt direction = Direction( aMediaLine, aSdpDocument.AttributeFields() );
+    CSdpConnectionField* connectionField = aSdpDocument.ConnectionField();
+    if ( connectionField == NULL )
+        {
+    	connectionField = ( aMediaLine.ConnectionFields()[0] )	;
+    	}
+
+    if ( connectionField->Address() == KMceSipNullAddress )	
+        {
+        direction = SdpCodecStringConstants::EAttributeSendonly;    
+        }
+    UpdateStreamL( aStream, direction );
+    aStream.SetDirection( direction, KMceNoEndpointAdjustment );
+	}
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodeDirectionL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeDirectionL( 
+    CMceComMediaStream& aStream, 
+    CSdpMediaField& aMedia,
+    CSdpDocument& aSdpDocument,
+    TMceNegotiationRole aRole ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeDirectionL(), Entry ")
+        
+    CMceSdpSession& sSession = aStream.Session()->SdpSession();
+
+    if ( aRole == EMceRoleOfferer && 
+    	 sSession.iOOldSchool &&  
+    	 aStream.Direction() != SdpCodecStringConstants::EAttributeSendrecv )
+    	     	 
+        {
+        CSdpConnectionField* connField = 
+            CSdpConnectionField::DecodeL( KMceSipNullAddressA );
+        aSdpDocument.SetConnectionField( connField );
+        MCEMM_DEBUG("using old school")
+        }
+    
+    else
+        {
+        RStringF direction = SDP_STRING( aStream.Direction() );
+
+        CSdpAttributeField* mediaAttr = 
+            CSdpAttributeField::NewLC( direction, KNullDesC8 );
+            
+        MCEMM_DEBUG_SVALUE("encoded direction", mediaAttr->Attribute().DesC() )
+            
+        aMedia.AttributeFields().AppendL( mediaAttr );
+        CleanupStack::Pop( mediaAttr );
+        }
+    
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeDirectionL(), Exit ")
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodePreconditionsL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodePreconditionsL( 
+    CMceComMediaStream& aStream,
+    CSdpMediaField& aMediaLine,
+    TMceNegotiationRole aRole ) const
+    {
+    CMceSecureMediaSession* secureSession = aStream.Session()->SecureSession();
+
+    if ( aStream.Session()->Modifier( KMcePreconditions ) == KMcePreconditionsSupported &&
+            !secureSession)
+        {
+        if ( ( aRole == EMceRoleOfferer && 
+               aStream.Session()->iUseLocalPreconditions ) ||
+             ( aRole == EMceRoleAnswerer && 
+               aStream.Session()->iUseRemotePreconditions ) )
+            {
+             TMcePreconditions* precondition = aStream.PreconditionsL( KMcePreconditions );
+             if ( precondition )
+	        	{
+	        	precondition->EncodeL( aMediaLine );
+	        	}
+            }
+        }
+  	if ( aStream.Session()->Modifier( KMceSecPreconditions ) == KMcePreconditionsE2ESupported )
+        {
+        TMcePreconditions* precondition = aStream.PreconditionsL( KMceSecPreconditions );
+        if ( precondition )
+        	{
+        	precondition->EncodeL( aMediaLine );
+        	}
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodePreconditionsL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode CMceMediaSdpCodec::DecodePreconditionsL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream,
+    TMceNegotiationRole aRole ) const
+    {
+	MCEMM_DEBUG("CMceMediaSdpCodec::DecodePreconditionsL EntryL")
+	TMceSipWarningCode warning = KErrNone;
+	
+    if ( aStream.Session()->Modifier( KMcePreconditions ) == KMcePreconditionsSupported  )
+    	{
+    	if ( ( aRole == EMceRoleOfferer && 
+               aStream.Session()->iUseLocalPreconditions ) ||
+             ( aRole == EMceRoleAnswerer && 
+               aStream.Session()->iUseRemotePreconditions )  )
+    		{
+    		aStream.PreconditionsL( KMcePreconditions )->DecodeL( aMediaLine );	
+    		
+	        }
+        }   
+	if ((aRole == EMceRoleOfferer && 
+     	aStream.Session()->iClientCryptoSuites.Count()
+     	&& aStream.Session()->Modifier( KMceSecPreconditions ) 
+     	== KMcePreconditionsE2ESupported )
+     	|| ( aRole ==EMceRoleAnswerer && (
+     		aStream.Session()->iRemoteSecPreconditionsRequired ||
+     		 aStream.Session()->iClientCryptoSuites.Count() )))
+      
+     	{
+		TMcePreconditions* precondition = 
+			aStream.PreconditionsL( KMceSecPreconditions, &aMediaLine );
+	
+    	if ( !precondition )
+    		{
+    		return KErrNone;
+    		}
+    	if ( warning && aStream.Preconditions().Count() )
+    		{
+    			//normal segmented precondition cases
+    		aStream.Session()->iRemoteSecPreconditionsRequired = EFalse;
+    		aStream.Session()->Modifier( KMceSecPreconditions ) = 
+    			KMcePreconditionsNotUsed;
+    		MCEMM_DEBUG("Secure preconds not used")	
+    		MCEMM_DEBUG("CMceMediaSdpCodec::DecodePreconditionsL Exit")	
+    		return KErrNone;
+    		}
+    
+    	if ( !precondition->IsMet() )
+    		{
+    		MCEMM_DEBUG("Decode Secure Precondition")	
+    		warning = precondition->DecodeL( aMediaLine );	
+    		}
+    	warning = warning == KMceSipPreconditionFailure ? 
+     			warning : KErrNone;
+     	MCEMM_DEBUG_DVALUE ("Decode Secure Precondition warning", warning ) 
+     	}        
+   	MCEMM_DEBUG("CMceMediaSdpCodec::DecodePreconditionsL Exit")	
+	return warning;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::EncodeClientAttributesL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::EncodeClientAttributesL( 
+    CMceComMediaStream& aStream,
+    CSdpMediaField& aMediaLine ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeClientAttributesL, Entry" )
+    
+    CDesC8Array* clientAttributes = aStream.iLocalMediaSDPLines;
+    __ASSERT_ALWAYS( clientAttributes, User::Leave( KErrArgument ) );
+
+    CMceSdpCodec::EncodeClientSdpFieldsL<CSdpMediaField>( *clientAttributes, aMediaLine );
+    
+        
+    MCEMM_DEBUG("CMceMediaSdpCodec::EncodeClientAttributesL, Exit" )
+    }    
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodeClientAttributesL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::DecodeClientAttributesL( 
+    CSdpMediaField& aMediaLine, 
+    CMceComMediaStream& aStream ) const
+    {
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeClientAttributesL, Entry" )
+    CDesC8Array* remoteAttributes = 
+        new (ELeave) CDesC8ArrayFlat( KMceArrayGranularity );
+    CleanupStack::PushL( remoteAttributes );
+    CBufFlat* encodeBuf = NULL;
+    
+    for ( TInt i = 0; i < aMediaLine.AttributeFields().Count(); i++ )
+        {
+    	encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
+    	CleanupStack::PushL( encodeBuf );
+    	RBufWriteStream writeStream( *encodeBuf, 0 );
+	    writeStream.PushL();
+        
+        aMediaLine.AttributeFields()[ i ]->EncodeL( writeStream );
+        MCEMM_DEBUG_SVALUE( "found attribute", encodeBuf->Ptr( 0 ) )
+        remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) );
+    	
+    	CleanupStack::PopAndDestroy(); // writeStream
+        CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf
+        }
+    
+    for ( TInt i = 0; i < aMediaLine.BandwidthFields().Count(); i++ )
+        {
+        
+    	encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
+    	CleanupStack::PushL( encodeBuf );
+    	RBufWriteStream writeStream( *encodeBuf, 0 );
+	    writeStream.PushL();
+        
+        aMediaLine.BandwidthFields()[ i ]->EncodeL( writeStream );
+        MCEMM_DEBUG_SVALUE("found attribute", encodeBuf->Ptr( 0 ) )
+        remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) );
+    	
+    	CleanupStack::PopAndDestroy(); // writeStream
+        CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf
+        }
+        
+    if ( aStream.BoundStream() )
+        {
+        MCEMM_DEBUG("copy attributes to bound stream" )
+        // copy attributes to bound stream
+        CMceComMediaStream& boundStream = aStream.BoundStreamL();
+        CDesC8Array* copyAttributes = 
+            new (ELeave) CDesC8ArrayFlat( KMceArrayGranularity );
+        CleanupStack::PushL( copyAttributes );
+        for ( TInt i = 0; i < remoteAttributes->MdcaCount(); i++ )
+            {
+            copyAttributes->AppendL( remoteAttributes->MdcaPoint( i ) );
+            }
+        CleanupStack::Pop( copyAttributes );
+        MCE_DELETE( boundStream.iRemoteMediaSDPLines );
+        boundStream.iRemoteMediaSDPLines = copyAttributes;
+        }
+        
+    CleanupStack::Pop( remoteAttributes );
+    MCE_DELETE( aStream.iRemoteMediaSDPLines );
+    aStream.iRemoteMediaSDPLines = remoteAttributes;
+    MCEMM_DEBUG("CMceMediaSdpCodec::DecodeClientAttributesL, Exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::ValidateSdp
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode CMceMediaSdpCodec::ValidateSdpL( 
+    CSdpMediaField& aMediaLine,
+    CSdpDocument& /*aSdpDocument*/ )
+    {
+    TMceSipWarningCode warning = KErrNone;
+    RArray<TUint> payloadTypes;
+    TInt error = KErrNone;
+    RPointerArray< CSdpFmtAttributeField >& formatLines =  
+                                            aMediaLine.FormatAttributeFields();
+
+    TInt dynamicPayloadsCount = 0;
+    TInt rtpmapCount = 0;
+    
+    error = DecodeFormatList( aMediaLine, payloadTypes );
+    
+    User::LeaveIfError( error );
+    
+    if ( error == KErrNone )
+        {
+        TInt index = 0;
+        while( index < payloadTypes.Count() )
+            {
+            dynamicPayloadsCount = payloadTypes[ index++ ] >= KMinDynamicPT ?
+                                   dynamicPayloadsCount + 1 : dynamicPayloadsCount;
+            }
+        index = 0;
+        while( index < formatLines.Count() )
+            {
+            rtpmapCount = formatLines[ index++ ]->Attribute() == 
+                                SDP_STRING( SdpCodecStringConstants::EAttributeRtpmap ) ?
+                          rtpmapCount + 1 : rtpmapCount;
+            }
+        
+        if ( dynamicPayloadsCount > 0 && rtpmapCount == 0 )
+            {
+            warning = KMceSipBadRequest;
+            }
+        }
+    else
+        {
+        warning = KMceSipServerInternalError;
+        }
+    
+    payloadTypes.Close();
+    
+    return warning;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::DecodePayloadsL
+// -----------------------------------------------------------------------------
+//
+TInt CMceMediaSdpCodec::DecodePayloadsL( 
+    CSdpMediaField& aMediaLine,
+    CMceComMediaStream& aStream,
+    TMceNegotiationRole aRole ) const
+    {
+    TInt decoded( 0 );
+    
+    RArray<TUint> payloadTypes;
+    CleanupClosePushL( payloadTypes );
+    
+    if ( aRole == EMceRoleAnswerer )
+        {
+        decoded = DecodeRtpmapLinesL( aMediaLine, aStream, EMceRoleAnswerer );
+        decoded += DecodeStaticPayloadsL( aMediaLine, aStream, payloadTypes, EMceRoleAnswerer );
+        }
+    else
+        { 
+        // static payloads are decoded first if role is offerer
+        decoded = DecodeStaticPayloadsL( aMediaLine, aStream, payloadTypes, EMceRoleOfferer );
+        decoded += DecodeRtpmapLinesL( aMediaLine, aStream, EMceRoleOfferer );
+        }
+        
+    UpdateSdpCodecIndexesL( aStream, payloadTypes );
+    CleanupStack::PopAndDestroy( &payloadTypes );
+    
+    return decoded;
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::UpdateSdpCodecIndexesL
+// -----------------------------------------------------------------------------
+//
+void CMceMediaSdpCodec::UpdateSdpCodecIndexesL( 
+    CMceComMediaStream& aStream,
+    RArray<TUint>& aPayloadTypes ) const
+    {
+    TInt index( 0 );
+    TInt codecSdpIndex( 0 );
+    while( index < aPayloadTypes.Count() )
+        {
+        TUint payload = aPayloadTypes[ index++ ];
+        CMceComCodec* codec = FindCodec( payload, aStream );
+        if ( codec )
+            {
+            codec->iCodecSdpIndex = codecSdpIndex++;
+            }  
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMceMediaSdpCodec::GetCorrespondingFmtpLineL
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CMceMediaSdpCodec::GetCorrespondingFmtpLineL( 
+    CSdpMediaField& aMediaLine, 
+    CSdpFmtAttributeField& aRtpMapFormatLine ) const
+    {
+    const TDesC8& payloadTypeInRtpMap = aRtpMapFormatLine.Format();
+    TUint rtpMapPT = ConvertDesToUintL( payloadTypeInRtpMap );
+    
+    RPointerArray< CSdpFmtAttributeField >& formatLines =  
+        aMediaLine.FormatAttributeFields();
+    
+    TPtrC8 fmtp( KNullDesC8() );
+    TBool found( EFalse );
+    for ( TInt j = 0; j < formatLines.Count() && !found; j++ )
+    	{
+    	CSdpFmtAttributeField* formatLine = formatLines[ j ];
+    	if ( formatLine->Attribute() == 
+    	            SDP_STRING( SdpCodecStringConstants::EAttributeFmtp ) )
+    		{
+    		TUint fmtpPT = ConvertDesToUintL( formatLine->Format() );
+    		if ( rtpMapPT == fmtpPT )
+    		    {
+    		    fmtp.Set( formatLine->Value() );
+    		    found = ETrue;
+    		    }
+    		}
+    	}
+    return fmtp;
+    }
+    
+// End of file