multimediacommsengine/mmcesrv/mmcemediamanager/src/mcepreconditions.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcepreconditions.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1850 @@
+/*
+* Copyright (c) 2005 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 "mcepreconditions.h"
+#include "sdpdocument.h"
+#include "sdpmediafield.h"
+#include "sdpattributefield.h"
+#include "sdpfmtattributefield.h"
+#include "mcesip.h"
+#include "sdpcodecstringpool.h"
+#include "sdpcodecstringconstants.h"
+#include "mcemmlogs.h"
+#include "mcemediastate.h"
+
+
+#define SDP_STRING( stringIndex )\
+    iStringPool.StringF( stringIndex, *iStringTable )
+
+        
+const TInt KCurrPrecType = 0;
+const TInt KCurrPrecStatusType = 1;
+const TInt KCurrPrecDirection = 2;
+
+const TInt KDesPrecType = 0;
+const TInt KDesPrecStrength = 1;
+const TInt KDesPrecStatusType = 2;
+const TInt KDesPrecDirection = 3;
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// TMcePreconditions::TMcePreconditions
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions::TMcePreconditions( CMceComMediaStream& aStream )
+    : iStream( aStream ),
+      iState( ECreated ),
+      iStringTable ( 0 ),
+      iType ( EQosPreconds )
+    {
+    }
+   
+// -----------------------------------------------------------------------------
+// TMcePreconditions::~TMcePreconditions
+// -----------------------------------------------------------------------------
+// 
+TMcePreconditions::~TMcePreconditions()
+    {
+    }
+    
+// -----------------------------------------------------------------------------
+// TMcePreconditions::ConstrucL
+// -----------------------------------------------------------------------------
+//
+void TMcePreconditions::ConstructL()
+    {
+    iStringPool = SdpCodecStringPool::StringPoolL();
+    iStringTable = &SdpCodecStringPool::StringTableL();
+
+    iKAttributeCurr = SDP_STRING( SdpCodecStringConstants::EAttributeCurr );
+    iKAttributeDes  = SDP_STRING( SdpCodecStringConstants::EAttributeDes );
+    iKAttributeConf = SDP_STRING( SdpCodecStringConstants::EAttributeConf );
+    iKAttributeNone = SDP_STRING( SdpCodecStringConstants::EAttributeStatusDirectionTagNone );
+
+    iKAttributeSend = SDP_STRING( SdpCodecStringConstants::EAttributeStatusDirectionTagSend );
+    iKAttributeRecv = SDP_STRING( SdpCodecStringConstants::EAttributeStatusDirectionTagRecv );
+    iKAttributeSendRecv = SDP_STRING( SdpCodecStringConstants::EAttributeStatusDirectionTagSendrecv );
+    
+    iKAttributeLocal = SDP_STRING( SdpCodecStringConstants::EAttributeStatusTypeLocal );
+    iKAttributeRemote = SDP_STRING( SdpCodecStringConstants::EAttributeStatusTypeRemote );
+
+    iKAttributeMandatory = SDP_STRING( SdpCodecStringConstants::EAttributeStatusStrengthTagMandatory );
+    iKAttributeOptional = SDP_STRING( SdpCodecStringConstants::EAttributeStatusStrengthTagOptional );
+
+    iKAttributeFailure = SDP_STRING( SdpCodecStringConstants::EAttributeStatusStrengthTagFailure );
+    iKAttributeUnknown = SDP_STRING( SdpCodecStringConstants::EAttributeStatusStrengthTagUnknown );
+	
+	iKAttributeEnd2End = SDP_STRING( SdpCodecStringConstants::EAttributeStatusTypeE2e );
+
+    DoConstructL();
+    }
+    
+// -----------------------------------------------------------------------------
+// TMcePreconditions::IsMet
+// -----------------------------------------------------------------------------
+//
+TBool TMcePreconditions::IsMet() const
+    {
+    return iState == EReserved;
+    }
+
+// -----------------------------------------------------------------------------
+// TMcePreconditions::IsMet
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions::TPreconditionType TMcePreconditions::Type()
+	{
+	return iType;
+	}
+	
+// -----------------------------------------------------------------------------
+// TMcePreconditions::ConstrucL
+// -----------------------------------------------------------------------------
+//
+void TMcePreconditions::ConstrucL( const TMcePreconditions& aPreconditions )
+    {
+    __ASSERT_ALWAYS( aPreconditions.iStringTable != NULL, 
+                     User::Leave( KErrArgument ) );
+
+    iState = aPreconditions.iState;
+    iStringPool = aPreconditions.iStringPool;
+    iStringTable = aPreconditions.iStringTable;
+
+    iKAttributeCurr = aPreconditions.iKAttributeCurr;
+    iKAttributeDes = aPreconditions.iKAttributeDes;
+    iKAttributeConf = aPreconditions.iKAttributeConf;
+    iKAttributeNone = aPreconditions.iKAttributeNone;
+
+    iKAttributeSend = aPreconditions.iKAttributeSend;
+    iKAttributeRecv = aPreconditions.iKAttributeRecv;
+    iKAttributeSendRecv = aPreconditions.iKAttributeSendRecv;
+   
+    iKAttributeLocal = aPreconditions.iKAttributeLocal;
+    iKAttributeRemote = aPreconditions.iKAttributeRemote;
+
+    iKAttributeMandatory = aPreconditions.iKAttributeMandatory;
+    iKAttributeOptional = aPreconditions.iKAttributeOptional;
+
+    iKAttributeFailure = aPreconditions.iKAttributeFailure;
+    iKAttributeUnknown = aPreconditions.iKAttributeUnknown;
+    
+    iKAttributeEnd2End = aPreconditions.iKAttributeEnd2End;   
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::TMceSegmentedPreconditions
+// -----------------------------------------------------------------------------
+//
+TMceSegmentedPreconditions::TMceSegmentedPreconditions( 
+    CMceComMediaStream& aStream )
+    : TMcePreconditions( aStream )
+    {
+    }  
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::CloneL
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions* TMceSegmentedPreconditions::CloneL( 
+    CMceComMediaStream& aStream )
+    {
+    TMceSegmentedPreconditions* copy = 
+        new (ELeave) TMceSegmentedPreconditions( aStream );
+    CleanupStack::PushL( copy );
+    copy->ConstrucL( *this );
+    CleanupStack::Pop( copy );
+    return copy;
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::ConstrucL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::ConstrucL( 
+    const TMceSegmentedPreconditions& aPreconditions )
+    {
+    TMcePreconditions::ConstrucL( aPreconditions );
+
+    iCurrentLocalStatus = aPreconditions.iCurrentLocalStatus;
+    iCurrentRemoteStatus = aPreconditions.iCurrentRemoteStatus;
+    iDesiredLocalSend = aPreconditions.iDesiredLocalSend;
+    iDesiredLocalRecv = aPreconditions.iDesiredLocalRecv;
+    
+    iDesiredRemoteSend = aPreconditions.iDesiredRemoteSend;
+    iDesiredRemoteRecv = aPreconditions.iDesiredRemoteRecv;
+
+    iConfirmation = aPreconditions.iConfirmation;
+    iType  = aPreconditions.iType;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DoConstructL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::DoConstructL()
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DoConstructL(), Entry ")
+    
+    iCurrentLocalStatus = iKAttributeNone;
+    iCurrentRemoteStatus = iKAttributeNone;
+    iDesiredLocalSend = iKAttributeNone;
+    iDesiredLocalRecv = iKAttributeNone;
+    iDesiredRemoteSend = iKAttributeNone;
+    iDesiredRemoteRecv = iKAttributeNone;
+    iConfirmation = iKAttributeNone;
+    iType = TMcePreconditions::EQosPreconds;
+    
+    TInt direction = iStream.Direction();
+    direction = direction == SdpCodecStringConstants::EAttributeInactive ? 
+                iStream.SdpStreamType() : direction;
+    
+    switch( direction )
+        {
+        case SdpCodecStringConstants::EAttributeSendrecv:
+            {
+            SetDesiredStatus( iKAttributeLocal, iKAttributeSendRecv, iKAttributeMandatory );
+            MCEMM_DEBUG_SVALUE("desired direction ", iKAttributeSendRecv.DesC() )
+            break;
+            }
+        case SdpCodecStringConstants::EAttributeSendonly:
+            {
+            SetDesiredStatus( iKAttributeLocal, iKAttributeSend, iKAttributeMandatory );
+            MCEMM_DEBUG_SVALUE("desired direction ", iKAttributeSend.DesC() )
+            break;
+            }
+        case SdpCodecStringConstants::EAttributeRecvonly:
+            {
+            SetDesiredStatus( iKAttributeLocal, iKAttributeRecv, iKAttributeMandatory );
+            MCEMM_DEBUG_SVALUE("desired direction ", iKAttributeRecv.DesC() )
+            break;
+            }
+        default:
+            {
+            User::Leave( KErrArgument );
+            }
+        }
+        
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DoConstructL(), Exit ")        
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::EncodeL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::EncodeL( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeL(), Entry ")
+    
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+    //if it is MT but does not decoded anything then we should not add in 183
+	if ( role == EMceRoleAnswerer && iState == ECreated && 
+		iStream.PreconditionsL( KMceSecPreconditions ) )
+		{
+		return;
+		}
+    //currentLocalStatus
+    EncodeCurrentStatusL( aMedia, iKAttributeLocal );
+
+    //currentRemoteStatus
+    EncodeCurrentStatusL( aMedia, iKAttributeRemote );
+    
+    //desiredLocalStatus
+    EncodeDesiredStatusL( aMedia, iKAttributeLocal );
+    
+    //desiredRemoteStatus
+    EncodeDesiredStatusL( aMedia, iKAttributeRemote );
+
+    //if answerer and confirmation is needed based on offerer's 
+    //reservation status
+    if ( role == EMceRoleAnswerer && RemoteReservationNeeded() )
+        {
+        iConfirmation = DesiredDirection( iKAttributeRemote );
+        EncodeConfirmationL( aMedia );
+        }
+        
+    if ( role == EMceRoleOfferer )
+        {
+        if ( iConfirmation != iKAttributeNone )
+            {
+            iState = EReserved;
+            iConfirmation = iKAttributeNone;
+            }
+        else
+            {
+            iState = ENegotiating;
+            }
+        }
+    else
+        {
+        //reset confirmation
+    	iConfirmation = iKAttributeNone;
+    
+    	//if not allready e2e reserved
+    	if ( !IsMet() )
+        	{
+        	SetState();
+        	}
+        }   
+	    
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeL(), Exit ") 
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode TMceSegmentedPreconditions::DecodeL( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeL(), Entry ")
+
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+    
+    TInt decoded = 0;
+    TInt index = 0;
+    
+    for( index = 0; index < attributes.Count(); index++ )
+        {
+        CSdpAttributeField* attribute = attributes[ index ];
+        //if offerer and there is confirmation request
+        if ( attribute->Attribute() == iKAttributeConf && 
+             role == EMceRoleOfferer )
+            {
+            decoded += DecodeConfStatusL( *attribute );
+            }
+        //current and desired statuses are only decoded when reservation
+        //is still ongoing
+        else if ( !IsMet() )
+            {
+            //decode current status
+            if ( attribute->Attribute() == iKAttributeCurr )
+                {
+                decoded += DecodeCurrentStatusL( *attribute );
+                }
+            //decode desired status
+            else if ( attribute->Attribute() == iKAttributeDes )
+                {
+                decoded += DecodeDesiredStatusL( *attribute );
+                }
+            else
+                {
+                //NOP
+                }
+            }
+        else
+            {
+            //NOP
+            }
+        }
+
+    //if something was decoeded
+    if ( decoded )
+        {
+        SetState();
+        }
+    else	
+        {
+        //if nothing was decoded. For example preconditions were sent
+        //but nothing received. This is interpretet as resources are reserved
+        iState = EReserved;
+        iCurrentRemoteStatus = DesiredDirection( iKAttributeRemote );
+        iCurrentRemoteStatus = ( iCurrentRemoteStatus == iKAttributeNone ) ?
+            DecodeMediaDirectionL( DesiredDirection( iKAttributeLocal ).DesC() ) : 
+            iCurrentRemoteStatus;
+        }
+        
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeL(), Exit ")
+    return KErrNone;
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::EncodeCurrentStatusL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::EncodeCurrentStatusL( 
+    CSdpMediaField& aMedia,
+    RStringF aAccessNetwork ) const
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeCurrentStatusL(), Entry ")
+    MCEMM_DEBUG_SVALUE("access network", aAccessNetwork.DesC() )
+    
+    HBufC8* currentStatus = NULL;
+    CSdpAttributeField* qosLine = NULL;
+    RStringF current = aAccessNetwork == iKAttributeLocal ? 
+                       iCurrentLocalStatus : iCurrentRemoteStatus;
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+                       
+                           
+    currentStatus = CurrentStausTextLC( aAccessNetwork.DesC(),
+                                        current.DesC() );
+                                        
+    qosLine = CSdpAttributeField::NewLC( iKAttributeCurr, *currentStatus );
+    MCEMM_DEBUG_SVALUE("encoded current status", qosLine->Value() )
+    attributes.AppendL( qosLine );
+    CleanupStack::Pop( qosLine );
+    CleanupStack::PopAndDestroy( currentStatus );
+    
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeCurrentStatusL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::EncodeDesiredStatusL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::EncodeDesiredStatusL( 
+    CSdpMediaField& aMedia,
+    RStringF aAccessNetwork ) const
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeDesiredStatusL(), Entry ")
+    MCEMM_DEBUG_SVALUE("access network", aAccessNetwork.DesC() )
+    
+    HBufC8* desiredStatus = NULL;
+    CSdpAttributeField* qosLine = NULL;
+    RStringF desiredSend = aAccessNetwork == iKAttributeLocal ? 
+                           iDesiredLocalSend : iDesiredRemoteSend;
+    RStringF desiredRecv = aAccessNetwork == iKAttributeLocal ? 
+                           iDesiredLocalRecv : iDesiredRemoteRecv;
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+                           
+    if ( desiredSend == desiredRecv )
+        {
+        desiredStatus = DesiredStausTextLC( desiredSend.DesC(),
+                                            aAccessNetwork.DesC(),
+                                            iKAttributeSendRecv.DesC() );
+        qosLine = CSdpAttributeField::NewLC( iKAttributeDes, *desiredStatus );
+        MCEMM_DEBUG_SVALUE("encoded desired send & recv status", qosLine->Value() )
+        attributes.AppendL( qosLine );
+        CleanupStack::Pop( qosLine );
+        CleanupStack::PopAndDestroy( desiredStatus );
+        }
+    else
+        {
+        desiredStatus = DesiredStausTextLC( desiredSend.DesC(),
+                                            aAccessNetwork.DesC(),
+                                            iKAttributeSend.DesC() );
+        qosLine = CSdpAttributeField::NewLC( iKAttributeDes, *desiredStatus );
+        MCEMM_DEBUG_SVALUE("encoded desired send status", qosLine->Value() )
+        attributes.AppendL( qosLine );
+        CleanupStack::Pop( qosLine );
+        CleanupStack::PopAndDestroy( desiredStatus );
+
+        desiredStatus = DesiredStausTextLC( desiredRecv.DesC(),
+                                            aAccessNetwork.DesC(),
+                                            iKAttributeRecv.DesC() );
+        qosLine = CSdpAttributeField::NewLC( iKAttributeDes, *desiredStatus );
+        MCEMM_DEBUG_SVALUE("encoded desired recv status", qosLine->Value() )
+        attributes.AppendL( qosLine );
+        CleanupStack::Pop( qosLine );
+        CleanupStack::PopAndDestroy( desiredStatus );   
+        }
+    
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeDesiredStatusL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::EncodeConfirmationL
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::EncodeConfirmationL( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeConfirmationL(), Entry ")
+    
+    if ( iConfirmation != iKAttributeNone )
+        {
+        HBufC8* confirmation = NULL;
+        CSdpAttributeField* qosLine = NULL;
+        RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+                               
+        confirmation = CurrentStausTextLC( iKAttributeRemote.DesC(),
+                                           iConfirmation.DesC() );
+                                            
+        qosLine = CSdpAttributeField::NewLC( iKAttributeConf, *confirmation );
+        MCEMM_DEBUG_SVALUE("encoded confirmation status", qosLine->Value() )
+        attributes.AppendL( qosLine );
+        CleanupStack::Pop( qosLine );
+        CleanupStack::PopAndDestroy( confirmation );
+        }
+        
+    MCEMM_DEBUG("TMceSegmentedPreconditions::EncodeConfirmationL(), Exit ")   
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeCurrentStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSegmentedPreconditions::DecodeCurrentStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeCurrentStatusL(), Entry ")
+    
+    TUint decoded = (TUint)ETrue;
+    TPtrC8 accessNetworkDesc;
+    TPtrC8 directionDesc;
+    
+    if ( ParseCurrentStatus( aAttribute.Value(), accessNetworkDesc, directionDesc ) == KErrNone )
+        {
+        if ( accessNetworkDesc == iKAttributeLocal.DesC() )
+            {
+            SetRemoteStatus( DecodeMediaDirectionL( directionDesc ) );
+            MCEMM_DEBUG_SVALUE("decoded current status", aAttribute.Value() )
+            }
+        }
+    else
+        {
+        decoded = (TUint)EFalse;
+        }
+
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeCurrentStatusL(), Exit ")
+    return decoded;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeDesiredStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSegmentedPreconditions::DecodeDesiredStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeCurrentStatusL(), Entry ")
+
+    TUint decoded = (TUint)ETrue;
+
+    TPtrC8 strengthDesc; 
+    TPtrC8 accessNetworkDesc;
+    TPtrC8 directionDesc;
+    
+    if ( ParseDesiredStatus( aAttribute.Value(), 
+                             strengthDesc, accessNetworkDesc, directionDesc ) == KErrNone )
+        {
+        if ( accessNetworkDesc == iKAttributeLocal.DesC() )
+            {
+            RStringF strength = DecodeStrengthL( strengthDesc );
+            RStringF direction = DecodeMediaDirectionL( directionDesc );
+            SetDesiredStatus( iKAttributeRemote, direction, strength );
+            MCEMM_DEBUG_SVALUE("decoded desired status", aAttribute.Value() )
+            }
+        }
+    else
+        {
+        decoded = (TUint)EFalse;
+        }
+
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeCurrentStatusL(), Exit ")
+    return decoded;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::SetRemoteStatus
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::SetRemoteStatus( RStringF aDirection )
+    {
+    if ( iCurrentRemoteStatus == iKAttributeNone ||
+         aDirection == iKAttributeSendRecv )
+        {
+        iCurrentRemoteStatus = aDirection;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeConfStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSegmentedPreconditions::DecodeConfStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeConfStatusL(), Entry ")
+
+    TUint decoded = (TUint)ETrue;
+
+    TPtrC8 accessNetworkDesc;
+    TPtrC8 directionDesc;
+    
+    if ( ParseCurrentStatus( aAttribute.Value(), accessNetworkDesc, directionDesc ) == KErrNone )
+        {
+        if ( accessNetworkDesc == iKAttributeRemote.DesC() )
+            {
+            iConfirmation = DecodeMediaDirectionL( directionDesc );
+            MCEMM_DEBUG_SVALUE("decoded confirmation", aAttribute.Value() )
+            }
+        else
+            {
+            decoded = (TUint)EFalse;
+            }
+        }
+    else
+        {
+        decoded = (TUint)EFalse;
+        }
+    
+    MCEMM_DEBUG("TMceSegmentedPreconditions::DecodeConfStatusL(), Exit ")
+    return decoded;
+        
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::SetState
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::SetState()
+    {
+    iState = ENegotiating;
+    
+    if ( !ReservationNeeded() &&
+         !RemoteReservationNeeded() &&
+         iConfirmation == iKAttributeNone )
+        {
+        iState = EReserved;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::SetDesiredStatus
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::SetDesiredStatus( RStringF aAccessNetwork,
+                                                   RStringF aDirection, 
+                                                   RStringF aStrength )
+    {
+    RStringF& desiredStatusSend = aAccessNetwork == iKAttributeLocal ? 
+                                 iDesiredLocalSend : iDesiredRemoteSend;
+    RStringF& desiredStatusRecv = aAccessNetwork == iKAttributeLocal ? 
+                                 iDesiredLocalRecv : iDesiredRemoteRecv;
+    
+    if ( aDirection == iKAttributeSend )
+        {
+        desiredStatusSend = aStrength;
+        }
+    else if ( aDirection == iKAttributeRecv )
+        {
+        desiredStatusRecv = aStrength;
+        }
+    else 
+        {
+        desiredStatusSend = aStrength;
+        desiredStatusRecv = aStrength;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DesiredDirection
+// -----------------------------------------------------------------------------
+//
+RStringF TMceSegmentedPreconditions::DesiredDirection( RStringF aAccessNetwork )
+    {
+    RStringF desiredStatus = iKAttributeNone;
+    
+    RStringF desiredStatusSend = aAccessNetwork == iKAttributeLocal ? 
+                                 iDesiredLocalSend : iDesiredRemoteSend;
+    RStringF desiredStatusRecv = aAccessNetwork == iKAttributeLocal ? 
+                                 iDesiredLocalRecv : iDesiredRemoteRecv;
+
+    if ( desiredStatusSend == iKAttributeMandatory &&
+         desiredStatusRecv == iKAttributeMandatory )
+        {
+        desiredStatus = iKAttributeSendRecv;
+        }
+    else if ( desiredStatusSend == iKAttributeMandatory &&
+              desiredStatusRecv != iKAttributeMandatory )
+        {
+        desiredStatus = iKAttributeSend;
+        }
+    else if ( desiredStatusSend != iKAttributeMandatory &&
+              desiredStatusRecv == iKAttributeMandatory )
+        {
+        desiredStatus = iKAttributeRecv;
+        }
+    else
+        {
+        //none
+        }
+        
+    return desiredStatus;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DesiredStausTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* TMceSegmentedPreconditions::DesiredStausTextLC( const TDesC8& aStrength, 
+                                                        const TDesC8& aAccessNetwork, 
+                                                        const TDesC8& aMediaDirection ) const
+    {
+    TInt desStatusTextLength = KMceSipSdpSegPrecDesiredStatusPattern().Length() +
+                               aStrength.Length() +
+                               aAccessNetwork.Length() +
+                               aMediaDirection.Length();
+    
+    HBufC8* desiredStatusText = HBufC8::NewLC( desStatusTextLength );
+    desiredStatusText->Des().AppendFormat( KMceSipSdpSegPrecDesiredStatusPattern,
+                                           &aStrength, &aAccessNetwork,
+                                           &aMediaDirection );
+    return desiredStatusText;
+    } 
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::CurrentStausTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* TMceSegmentedPreconditions::CurrentStausTextLC( const TDesC8& aAccessNetwork, 
+                                                        const TDesC8& aMediaDirection ) const
+    {
+    TInt curStatusTextLength = KMceSipSdpSegPrecCurrentStatusPattern().Length() + 
+                                  aAccessNetwork.Length() +
+                                  aMediaDirection.Length();
+    
+    HBufC8* currentStatusText = HBufC8::NewLC( curStatusTextLength );
+    currentStatusText->Des().AppendFormat( KMceSipSdpSegPrecCurrentStatusPattern,
+                                             &aAccessNetwork,
+                                             &aMediaDirection );
+
+    return currentStatusText;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::ParseCurrentStatus
+// -----------------------------------------------------------------------------
+//
+TInt TMceSegmentedPreconditions::ParseCurrentStatus( const TDesC8& aLine,
+                                                     TPtrC8& aAccessNetwork,
+                                                     TPtrC8& aMediaDirection )
+    {
+    TLex8 attribute( aLine );
+    TInt tokenNbr = 0;
+    
+    while( !attribute.Eos() )
+        {
+        TPtrC8 token = attribute.NextToken();
+        if ( tokenNbr == KCurrPrecType )
+            {
+            if ( token != KMceSipSdpQos )
+                {
+                return KErrNotFound;
+                }
+            }
+        else if ( tokenNbr == KCurrPrecStatusType )
+            {
+            aAccessNetwork.Set( token );
+            }
+        else if ( tokenNbr == KCurrPrecDirection )
+            {
+            aMediaDirection.Set( token );
+            }
+        else
+            {
+            //ignore trailing tokens
+            }
+        tokenNbr++;
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::ParseDesiredStatus
+// -----------------------------------------------------------------------------
+//
+TInt TMceSegmentedPreconditions::ParseDesiredStatus( const TDesC8& aLine,
+                                                     TPtrC8& aStrength,
+                                                     TPtrC8& aAccessNetwork,
+                                                     TPtrC8& aMediaDirection )
+    {
+    TLex8 attribute( aLine );
+    TInt tokenNbr = 0;
+    
+    while( !attribute.Eos() )
+        {
+        TPtrC8 token = attribute.NextToken();
+
+        if ( tokenNbr == KDesPrecType )
+            {
+            if ( token != KMceSipSdpQos )
+                {
+                return KErrNotFound;
+                }
+            }
+        else if ( tokenNbr == KDesPrecStrength )
+            {
+            aStrength.Set( token );
+            }
+        else if ( tokenNbr == KDesPrecStatusType )
+            {
+            aAccessNetwork.Set( token );
+            }
+        else if ( tokenNbr == KDesPrecDirection )
+            {
+            aMediaDirection.Set( token );
+            }
+        else
+            {
+            //ignore trailing tokens
+            }
+        tokenNbr++;
+        }
+    
+    return KErrNone;    
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeMediaDirectionL
+// -----------------------------------------------------------------------------
+//
+RStringF TMceSegmentedPreconditions::DecodeMediaDirectionL( const TDesC8& aMediaDirection )
+    {
+    RStringF mediaDirection = iKAttributeNone;
+    
+    RStringF direction = iStringPool.OpenFStringL( aMediaDirection );
+    CleanupClosePushL( direction );
+
+    if ( direction == iKAttributeSend )
+        {
+        mediaDirection = iKAttributeRecv;
+        }
+    else if ( direction == iKAttributeRecv )
+        {
+        mediaDirection = iKAttributeSend;
+        }
+    else if ( direction == iKAttributeSendRecv )
+        {
+        mediaDirection = iKAttributeSendRecv;
+        }
+    else if ( direction == iKAttributeNone )
+        {
+        mediaDirection = iKAttributeNone;
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+        
+    CleanupStack::PopAndDestroy();//direction
+    
+    return mediaDirection;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::DecodeStrengthL
+// -----------------------------------------------------------------------------
+//
+RStringF TMceSegmentedPreconditions::DecodeStrengthL( const TDesC8& aStrength )
+    {
+    RStringF strength = iKAttributeNone;
+    
+    RStringF tmpStrength = iStringPool.OpenFStringL( aStrength );
+    CleanupClosePushL( tmpStrength );
+
+    if ( tmpStrength == iKAttributeMandatory )
+        {
+        strength = iKAttributeMandatory;
+        }
+    else if ( tmpStrength == iKAttributeOptional )
+        {
+        strength = iKAttributeOptional;
+        }
+    else if ( tmpStrength == iKAttributeNone )
+        {
+        strength = iKAttributeNone;
+        }
+    else if ( tmpStrength == iKAttributeFailure )
+        {
+        strength = iKAttributeFailure;
+        }
+    else if ( tmpStrength == iKAttributeUnknown )
+        {
+        strength = iKAttributeUnknown;
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+        
+    CleanupStack::PopAndDestroy();//tmpStrength
+    
+    return strength;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::Reserved
+// -----------------------------------------------------------------------------
+//
+void TMceSegmentedPreconditions::Reserved()
+    {
+    //Mark local resources as reserved
+    iCurrentLocalStatus = DesiredDirection( iKAttributeLocal );
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::ReservationNeeded
+// -----------------------------------------------------------------------------
+//
+TBool TMceSegmentedPreconditions::RemoteReservationNeeded() const
+    {
+    return iCurrentRemoteStatus == iKAttributeNone;  
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSegmentedPreconditions::ReservationNeeded
+// -----------------------------------------------------------------------------
+//
+TBool TMceSegmentedPreconditions::ReservationNeeded() const
+    {
+    return iCurrentLocalStatus == iKAttributeNone;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::TMceSecurePreconditions
+// -----------------------------------------------------------------------------
+//
+TMceSecurePreconditions::TMceSecurePreconditions( CMceComMediaStream& aStream )                                                    
+    : TMcePreconditions( aStream )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::CloneL
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions* TMceSecurePreconditions::CloneL( 
+    CMceComMediaStream& aStream )
+    {
+    TMceSecurePreconditions* copy = 
+        new (ELeave) TMceSecurePreconditions( aStream );
+    CleanupStack::PushL( copy );
+    copy->ConstrucL( *this );
+    CleanupStack::Pop( copy );
+    return copy;
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::ConstrucL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::ConstrucL( 
+    const TMceSecurePreconditions& aPreconditions )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::ConstructL(), Entry ")
+    TMcePreconditions::ConstrucL( aPreconditions );
+
+    iCurrentLocalStatus = aPreconditions.iCurrentLocalStatus;
+    iCurrentRemoteStatus = aPreconditions.iCurrentRemoteStatus;
+    MCEMM_DEBUG_SVALUE("iCurrentRemoteStatus", iCurrentRemoteStatus.DesC() )
+    iDesiredLocalSendRecv = aPreconditions.iDesiredLocalSendRecv;
+    
+    iDesiredRemoteSendRecv = aPreconditions.iDesiredRemoteSendRecv;
+
+    iConfirmation = aPreconditions.iConfirmation;
+    
+    iType = aPreconditions.iType;
+    MCEMM_DEBUG("TMceSecurePreconditions::ConstructL(), Exit ")     
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DoConstructL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::DoConstructL()
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::DoConstructL(), Entry ")
+    
+    iCurrentLocalStatus = iKAttributeNone;
+    iCurrentRemoteStatus = iKAttributeNone;
+    iDesiredLocalSendRecv = iKAttributeNone;
+    iDesiredRemoteSendRecv = iKAttributeNone;
+    iConfirmation = iKAttributeNone;
+    iType = TMcePreconditions::ESecPreconds;
+    
+    TInt direction = iStream.Direction();
+    direction = direction == SdpCodecStringConstants::EAttributeInactive ? 
+        iStream.SdpStreamType() : direction;
+    
+    switch( direction )
+        {
+        case SdpCodecStringConstants::EAttributeSendrecv:
+        case SdpCodecStringConstants::EAttributeSendonly:
+        case SdpCodecStringConstants::EAttributeRecvonly:
+            {
+            SetDesiredStatus( iKAttributeLocal, iKAttributeMandatory );
+            MCEMM_DEBUG_SVALUE("desired direction ", iKAttributeSendRecv.DesC() )
+            break;
+            }
+        default:
+            {
+            User::Leave( KErrArgument );
+            }
+        }    
+    
+    MCEMM_DEBUG("TMceSecurePreconditions::DoConstructL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::EncodeL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::EncodeL( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeL(), Entry ")
+    
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+
+   //current e2e Status
+    EncodeCurrentStatusL( aMedia, role );
+    
+    //desired e2e Status
+    EncodeDesiredStatusL( aMedia );
+    if ( iDesiredRemoteSendRecv == iKAttributeFailure )
+    	{
+    	iDesiredLocalSendRecv = iDesiredRemoteSendRecv;  
+    	}
+    //if answerer and confirmation is needed based on offerer's 
+    //reservation status
+    if ( role == EMceRoleAnswerer && ReservationNeeded() )
+        {
+        iConfirmation = iKAttributeSendRecv;
+        EncodeConfirmationL( aMedia );
+        }
+        
+    //reset confirmation
+    iConfirmation = iKAttributeNone;
+    
+    //if not allready e2e reserved
+    if ( !IsMet() )
+        {
+        SetState();
+        }
+    
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeL
+// -----------------------------------------------------------------------------
+//
+TMceSipWarningCode TMceSecurePreconditions::DecodeL( CSdpMediaField& aMedia )
+    {		
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeL(), Entry ")
+	
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+    TMceSipWarningCode warning = KErrNone;
+    TInt decoded = 0;
+    TInt index = 0;
+    TBool anyPreconds = EFalse;
+    if ( FindSecPreconds( aMedia ) )
+    	{
+		for ( index = 0; index < attributes.Count(); index++ )
+		    {
+		    CSdpAttributeField* attribute = attributes[ index ];
+		    //if offerer and there is confirmation request
+		    if ( attribute->Attribute() == iKAttributeConf && 
+		         role == EMceRoleOfferer && 
+		         attribute->Value().Find( KMceSipSdpSec ) != KErrNotFound )
+		        {
+		        decoded += DecodeConfStatusL( *attribute );
+		        anyPreconds = ETrue;
+		        }
+		    //current and desired statuses are only decoded when reservation
+		    //is still ongoing
+		    else if ( !IsMet() || 
+		              iDesiredRemoteSendRecv == iKAttributeFailure ||
+		    		  iDesiredLocalSendRecv == iKAttributeFailure )
+		        {
+		        //decode current status
+		        if ( attribute->Attribute() == iKAttributeCurr && 
+		        	attribute->Value().Find( KMceSipSdpSec ) != KErrNotFound )
+		            {
+		            decoded += DecodeCurrentStatusL( *attribute );
+		            }
+		        //decode desired status
+		        else if ( attribute->Attribute() == iKAttributeDes &&
+		        		attribute->Value().Find( KMceSipSdpSec ) != KErrNotFound )
+		            {
+		            decoded += DecodeDesiredStatusL( *attribute );
+		            anyPreconds = ETrue;
+		            }
+		        else
+		            {
+		            //NOP
+		            }
+		        }
+		    else
+		        {
+		        //NOP
+		        }
+		    }
+
+		//if something was decoded
+		if ( decoded >= KMceSipPreconditionFailure )
+			{
+			iState = ECreated;
+			return warning = KMceSipPreconditionFailure;
+			}
+		else if ( decoded )
+		    {
+		    SetState();
+		    if ( EMceRoleOfferer == role &&
+		         iKAttributeNone == iCurrentLocalStatus )
+		        {
+		        //decoding provisional response
+		        iCurrentLocalStatus = iKAttributeRecv;
+		        }
+		    }
+		else
+		    {
+		    //NOP
+		    }
+    	}
+    
+    // If nothing was decoded or preconditions were not sent in response
+    // This is interpreted as resources are reserved  	
+    if ( !decoded || !FindSecPreconds( aMedia ) )   	
+    	{
+    	iState = EReserved;
+    	if ( iCurrentRemoteStatus == iKAttributeNone )
+    	    {
+    	    iCurrentRemoteStatus = iKAttributeSendRecv;
+    	    }
+
+	    //if there is required header but not any precondition present    
+	    if ( iStream.Session()->iRemoteSecPreconditionsRequired && !anyPreconds )
+	    	{
+	    	iDesiredRemoteSendRecv = iKAttributeFailure;
+	    	}
+    	}
+    	
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeL(), Exit ")
+    return warning;
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::EncodeCurrentStatusL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::EncodeCurrentStatusL( 
+    CSdpMediaField& aMedia,
+    TMceNegotiationRole aRole )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeCurrentStatusL(), Entry ")
+	
+    HBufC8* currentStatus = NULL;
+    CSdpAttributeField* secLine = NULL;
+	RStringF current = iKAttributeNone;
+    
+    if ( aRole == EMceRoleAnswerer && 
+         ReservationNeeded() )
+    	{
+    	current = iKAttributeRecv;
+    	iCurrentLocalStatus = current;
+    	}
+    else
+    	{
+    	if ( aRole == EMceRoleOfferer  )
+    	    {
+    	    if ( iCurrentLocalStatus != iKAttributeNone )
+    	        {
+    	        current = iKAttributeSendRecv;
+    	        }
+    	    }
+    	else // EMceRoleAnswerer
+    	    {
+    	    if ( iCurrentRemoteStatus != iKAttributeNone )
+    	        {
+    	        current = iKAttributeSendRecv;
+    	        iState = EReserved;
+    	        }		
+    	    }		
+    	}
+    
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();                   
+                           
+    currentStatus = CurrentStatusTextLC( current.DesC() );
+                                        
+    secLine = CSdpAttributeField::NewLC( iKAttributeCurr, *currentStatus );
+    MCEMM_DEBUG_SVALUE("encoded current status", secLine->Value() )
+    attributes.AppendL( secLine );
+    CleanupStack::Pop( secLine );
+    CleanupStack::PopAndDestroy( currentStatus );
+    
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeCurrentStatusL(), Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::EncodeDesiredStatusL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::EncodeDesiredStatusL( 
+    CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeDesiredStatusL(), Entry ")
+    
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+    HBufC8* desiredStatus = NULL;
+    CSdpAttributeField* secLine = NULL;
+   
+    RStringF desired = iDesiredRemoteSendRecv == iKAttributeNone ? 
+    			iKAttributeOptional : iKAttributeMandatory;  
+    // for 183 always upgraded to mandatory			                                 
+    desired = role ==  EMceRoleAnswerer ? iKAttributeMandatory : desired;	                                   
+    iDesiredLocalSendRecv = desired;
+    MCEMM_DEBUG_SVALUE("desired", desired.DesC() )    
+    
+    RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+    
+    if ( iDesiredRemoteSendRecv == iKAttributeFailure )
+    	{
+    	desiredStatus = DesiredStatusTextLC( iKAttributeFailure.DesC(),
+                                             iKAttributeSendRecv.DesC() );
+                                      
+    	}
+    else
+    	{
+    	desiredStatus = DesiredStatusTextLC( desired.DesC(),
+                                             iKAttributeSendRecv.DesC() );
+    	}
+    secLine = CSdpAttributeField::NewLC( iKAttributeDes, *desiredStatus );
+    MCEMM_DEBUG_SVALUE("encoded desired send & recv status", secLine->Value() )
+    attributes.AppendL( secLine );
+    CleanupStack::Pop( secLine );
+    CleanupStack::PopAndDestroy( desiredStatus );
+
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeDesiredStatusL(), Exit ")
+    }
+	
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::EncodeConfirmationL
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::EncodeConfirmationL( CSdpMediaField& aMedia )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeConfirmationL(), Entry ")
+    
+    if ( iConfirmation != iKAttributeNone )
+        {
+        HBufC8* confirmation = NULL;
+        CSdpAttributeField* secLine = NULL;
+        RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+                               
+        confirmation = CurrentStatusTextLC( iConfirmation.DesC() );
+                                            
+        secLine = CSdpAttributeField::NewLC( iKAttributeConf, *confirmation );
+        MCEMM_DEBUG_SVALUE("encoded confirmation status", secLine->Value() )
+        attributes.AppendL( secLine );
+        CleanupStack::Pop( secLine );
+        CleanupStack::PopAndDestroy( confirmation );
+        }
+        
+    MCEMM_DEBUG("TMceSecurePreconditions::EncodeConfirmationL(), Exit ")    
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeCurrentStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSecurePreconditions::DecodeCurrentStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeCurrentStatusL(), Entry ")
+    
+    TUint decoded = (TUint)EFalse;
+    TPtrC8 directionDesc;
+    
+    if ( ParseCurrentStatus( aAttribute.Value(), directionDesc ) )
+        {
+        decoded = (TUint)ETrue;
+        TBool decodePrackCurrentStatus =
+            ( iCurrentLocalStatus == iKAttributeRecv &&
+              iCurrentRemoteStatus == iKAttributeNone ) ? ETrue : EFalse;
+        TBool decode200OkCurrentStatus =
+            ( iCurrentLocalStatus == iKAttributeRecv &&
+              iCurrentRemoteStatus == iKAttributeSend ) ? ETrue : EFalse;
+        if ( decodePrackCurrentStatus && 
+             DecodeMediaDirectionL( directionDesc ) == iKAttributeNone )
+            {
+            //return 580 when decoding PRACK
+            decoded = (TUint ) KMceSipPreconditionFailure; 
+            iCurrentRemoteStatus == iKAttributeNone;
+            }
+        else if ( decode200OkCurrentStatus &&
+                  DecodeMediaDirectionL( directionDesc ) != iKAttributeSendRecv )
+            {
+            //return 580 when decoding 200OK
+            decoded = ( TUint ) KMceSipPreconditionFailure; 
+            iCurrentRemoteStatus == iKAttributeNone;
+            }
+        else
+            {
+            SetRemoteStatus( DecodeMediaDirectionL( directionDesc ) );
+            if ( decodePrackCurrentStatus || decode200OkCurrentStatus )
+                {
+                Reserved();
+                }     		
+            }
+        MCEMM_DEBUG_SVALUE("decoded current status", aAttribute.Value() )
+        }
+
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeCurrentStatusL(), Exit ")
+    return decoded;  
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeDesiredStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSecurePreconditions::DecodeDesiredStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeCurrentStatusL(), Entry ")
+
+    TUint decoded = ( TUint )EFalse;
+
+    TPtrC8 strengthDesc; 
+    TPtrC8 directionDesc;
+    TMceNegotiationRole role = iStream.Session()->NegotiationState().Role();
+    
+    if ( ParseDesiredStatus( aAttribute.Value(), strengthDesc, directionDesc ) )
+        {
+        decoded = ( TUint )ETrue;
+        RStringF strength = DecodeStrengthL( strengthDesc );
+        SetDesiredStatus( iKAttributeRemote, strength );
+        MCEMM_DEBUG_SVALUE("decoded desired status", aAttribute.Value() )
+            
+        if ( ( strength == iKAttributeMandatory && 
+               !iStream.Session()->iClientCryptoSuites.Count() ) ||
+             ( iCurrentLocalStatus == iKAttributeRecv && 
+               iCurrentRemoteStatus == iKAttributeNone  && 
+               role == EMceRoleAnswerer ) )
+            {
+            //there is no require header but desired status == mandatory
+            decoded = (TUint ) KMceSipPreconditionFailure;  
+            iDesiredRemoteSendRecv = iKAttributeFailure;
+            HBufC8* desiredValue = DesiredStatusTextLC( 
+                iKAttributeFailure.DesC(), iKAttributeSendRecv.DesC() );
+            aAttribute.SetL( iKAttributeDes, *desiredValue);
+            CleanupStack::PopAndDestroy( desiredValue );
+            }
+        if ( StrengthDowngraded( strength ) &&
+             iCurrentLocalStatus != iKAttributeNone )
+            {
+            //downgrading strength not allowed after initiating negotiation
+            MCEMM_DEBUG("Error: Strength downgraded")
+            return (TUint) KMceSipPreconditionFailure; 
+            }
+        if ( strength == iKAttributeFailure || 
+             iDesiredLocalSendRecv == iKAttributeFailure )	
+            {
+            decoded = (TUint ) KMceSipPreconditionFailure; 
+            }
+        if ( strength == iKAttributeOptional && 
+             !iStream.Session()->iClientCryptoSuites.Count() )
+            {
+            iStream.Session()->Modifier( KMceSecPreconditions ) = 
+                KMcePreconditionsNotUsed;
+            }
+        if ( strength == iKAttributeOptional && 
+             iStream.Session()->iClientCryptoSuites.Count() )
+            {
+            iStream.Session()->Modifier( KMceSecPreconditions ) = 
+                KMcePreconditionsE2ESupported;
+            iStream.Session()->Modifier( KMcePreconditions ) = 
+                KMcePreconditionsNotUsed;
+            iStream.Session()->iRemoteSecPreconditionsRequired = ETrue;
+            }
+        }
+
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeCurrentStatusL(), Exit ")
+	return decoded;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::SetCurrentStatus
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::SetRemoteStatus( RStringF aDirection )
+	{   
+   	if ( iCurrentRemoteStatus == iKAttributeNone ||
+         aDirection == iKAttributeSendRecv )
+        {
+        iCurrentRemoteStatus = aDirection;
+        }
+    } 
+    
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeConfStatusL
+// -----------------------------------------------------------------------------
+//
+TUint TMceSecurePreconditions::DecodeConfStatusL( 
+    CSdpAttributeField& aAttribute )
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeConfStatusL(), Entry ")
+
+    TUint decoded = ( TUint )EFalse;
+    TPtrC8 directionDesc;
+    
+    if ( ParseCurrentStatus( aAttribute.Value(), directionDesc ) )
+        {
+        decoded = (TUint)ETrue;
+        iConfirmation = DecodeMediaDirectionL( directionDesc );
+        MCEMM_DEBUG_SVALUE("decoded confirmation", aAttribute.Value() )
+        }
+    
+    MCEMM_DEBUG("TMceSecurePreconditions::DecodeConfStatusL(), Exit ")
+    return decoded;       
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::SetState
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::SetState()
+    {
+    MCEMM_DEBUG("TMceSecurePreconditions::SetState Entry ")
+    iState = ENegotiating;
+    
+    if ( iCurrentRemoteStatus == iKAttributeSendRecv && 
+         ( iDesiredRemoteSendRecv == iKAttributeMandatory ||
+     	   iDesiredRemoteSendRecv == iKAttributeOptional ) )
+     	{
+     	Reserved();
+     	}
+    if ( !ReservationNeeded() &&
+         !RemoteReservationNeeded() &&
+         iConfirmation == iKAttributeNone )
+        {
+        MCEMM_DEBUG("SetState as Reserved ")
+        iState = EReserved;
+        }
+    MCEMM_DEBUG_DVALUE ("Current Secure precondition STate ", iState )   
+    MCEMM_DEBUG("TMceSecurePreconditions::SetState Exit ")
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::SetDesiredStatus
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::SetDesiredStatus( 
+    RStringF aEntity,
+    RStringF aStrength )
+    {
+    if ( aEntity == iKAttributeLocal )
+        {
+        iDesiredLocalSendRecv = aStrength;
+        }
+    else
+        {
+        iDesiredRemoteSendRecv = aStrength;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DesiredStatusTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* TMceSecurePreconditions::DesiredStatusTextLC( 
+    const TDesC8& aStrength,  
+    const TDesC8& aMediaDirection ) const
+    {
+    TInt desStatusTextLength = 
+        KMceSipSdpSecPrecDesiredStatusPattern().Length() +
+        aStrength.Length() +
+        iKAttributeEnd2End.DesC().Length() +
+        aMediaDirection.Length();
+    
+    HBufC8* desiredStatusText = HBufC8::NewLC( desStatusTextLength );
+    desiredStatusText->Des().AppendFormat( 
+        KMceSipSdpSecPrecDesiredStatusPattern,
+        &aStrength, 
+        &( iKAttributeEnd2End.DesC() ),
+        &aMediaDirection );
+
+    return desiredStatusText;
+    } 
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::CurrentStatusTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* TMceSecurePreconditions::CurrentStatusTextLC( 
+    const TDesC8& aMediaDirection ) const
+    {
+    TInt curStatusTextLength = 
+        KMceSipSdpSecPrecCurrentStatusPattern().Length() + 
+        iKAttributeEnd2End.DesC().Length() +
+        aMediaDirection.Length();
+    
+    HBufC8* currentStatusText = HBufC8::NewLC( curStatusTextLength );
+    
+    currentStatusText->Des().AppendFormat( 
+        KMceSipSdpSecPrecCurrentStatusPattern,
+        &( iKAttributeEnd2End.DesC() ),
+        &aMediaDirection );
+
+    return currentStatusText;  
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::ParseCurrentStatus
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::ParseCurrentStatus( 
+    const TDesC8& aLine,
+    TPtrC8& aMediaDirection )
+    {
+    TLex8 attribute( aLine );
+    TInt tokenNbr = 0;
+    
+    while( !attribute.Eos() )
+        {
+        TPtrC8 token = attribute.NextToken();
+        if ( tokenNbr == KCurrPrecType )
+            {
+            if ( token != KMceSipSdpSec )
+                {
+                return EFalse;
+                }
+            }
+        else if ( tokenNbr == KCurrPrecStatusType )
+            {
+            if ( token != iKAttributeEnd2End.DesC() )
+                {
+                return EFalse;
+                }
+            }
+        else if ( tokenNbr == KCurrPrecDirection )
+            {
+            aMediaDirection.Set( token );
+            }
+        else
+            {
+            //ignore trailing tokens
+            }
+        tokenNbr++;
+        }
+
+    return ETrue;   
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::ParseDesiredStatus
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::ParseDesiredStatus( 
+    const TDesC8& aLine,
+    TPtrC8& aStrength,
+    TPtrC8& aMediaDirection )
+    {
+    TLex8 attribute( aLine );
+    TInt tokenNbr = 0;
+    
+    while( !attribute.Eos() )
+        {
+        TPtrC8 token = attribute.NextToken();
+
+        if ( tokenNbr == KDesPrecType )
+            {
+            if ( token != KMceSipSdpSec )
+                {
+                return EFalse;
+                }
+            }
+        else if ( tokenNbr == KDesPrecStrength )
+            {
+            aStrength.Set( token );
+            }
+        else if ( tokenNbr == KDesPrecStatusType )
+            {
+            if ( token != iKAttributeEnd2End.DesC() )
+                {
+                return EFalse;
+                }
+            }
+        else if ( tokenNbr == KDesPrecDirection )
+            {
+            aMediaDirection.Set( token );
+            }
+        else
+            {
+            //ignore trailing tokens
+            }
+        tokenNbr++;
+        }
+    
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeMediaDirectionL
+// -----------------------------------------------------------------------------
+//
+RStringF TMceSecurePreconditions::DecodeMediaDirectionL( 
+    const TDesC8& aMediaDirection )
+    {
+    RStringF mediaDirection = iKAttributeNone;
+    
+    RStringF direction = iStringPool.OpenFStringL( aMediaDirection );
+    CleanupClosePushL( direction );
+
+    if ( direction == iKAttributeSend )
+        {
+        mediaDirection = iKAttributeRecv;
+        }
+    else if ( direction == iKAttributeRecv )
+        {
+        mediaDirection = iKAttributeSend;
+        }
+    else if ( direction == iKAttributeSendRecv )
+        {
+        mediaDirection = iKAttributeSendRecv;
+        }
+    else if ( direction == iKAttributeNone )
+        {
+        mediaDirection = iKAttributeNone;
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+        
+    CleanupStack::PopAndDestroy();//direction
+    
+    return mediaDirection;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::DecodeStrengthL
+// -----------------------------------------------------------------------------
+//
+RStringF TMceSecurePreconditions::DecodeStrengthL( const TDesC8& aStrength )
+    {
+    RStringF strength = iKAttributeNone;
+    
+    RStringF tmpStrength = iStringPool.OpenFStringL( aStrength );
+    CleanupClosePushL( tmpStrength );
+
+    if ( tmpStrength == iKAttributeMandatory )
+        {
+        strength = iKAttributeMandatory;
+        }
+    else if ( tmpStrength == iKAttributeOptional )
+        {
+        strength = iKAttributeOptional;
+        }
+    else if ( tmpStrength == iKAttributeNone )
+        {
+        strength = iKAttributeNone;
+        }
+    else if ( tmpStrength == iKAttributeFailure )
+        {
+        strength = iKAttributeFailure;
+        }
+    else if ( tmpStrength == iKAttributeUnknown )
+        {
+        strength = iKAttributeUnknown;
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+        
+    CleanupStack::PopAndDestroy();//tmpStrength
+    
+    return strength;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::Reserved
+// -----------------------------------------------------------------------------
+//
+void TMceSecurePreconditions::Reserved()
+    {
+    iCurrentLocalStatus = iKAttributeSendRecv;
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::ReservationNeeded
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::RemoteReservationNeeded() const
+    {
+    return iCurrentRemoteStatus == iKAttributeNone;     
+    }
+    
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::ReservationNeeded
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::ReservationNeeded() const
+    {
+    return ( iCurrentLocalStatus == iKAttributeNone || 
+    		 iCurrentLocalStatus == iKAttributeRecv );
+    }
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::FindSecPreconds
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::FindSecPreconds( CSdpMediaField& aMedia )
+	{
+	TBool decodedSec = EFalse;
+	if ( &aMedia )
+		{
+		RPointerArray<CSdpAttributeField>& attributes = aMedia.AttributeFields();
+	    
+	    TInt index = 0;
+
+	    for( index = 0; index < attributes.Count(); index++ )
+		    {
+		    CSdpAttributeField* attribute = attributes[ index ];
+		    //decode current status
+		    
+		    if ( attribute->Attribute().DesC().Match( KMceSipSdpPreconditionCurr) != KErrNotFound )
+		        {
+		        TLex8 attributeValue( attribute->Value() );
+		    	TPtrC8 token = attributeValue.NextToken();
+			    if ( token == KMceSipSdpSec )
+			    	{
+			    	return decodedSec = ETrue;
+			       	}
+		        }
+	  		}
+		}
+	return decodedSec; 	
+	}	
+
+// -----------------------------------------------------------------------------
+// TMceSecurePreconditions::StrengthDowngraded
+// -----------------------------------------------------------------------------
+//
+TBool TMceSecurePreconditions::StrengthDowngraded( RStringF aStrength )
+    {
+    TBool decision( ETrue ); 
+    if ( aStrength == iDesiredLocalSendRecv )
+        {
+        decision = EFalse;
+        }
+    else if ( iDesiredLocalSendRecv == iKAttributeMandatory )
+        {
+        decision = ETrue;
+        }
+    else if ( iDesiredLocalSendRecv == iKAttributeOptional )
+        {
+        decision = !( aStrength == iKAttributeMandatory );
+        }
+    else
+        {
+        decision = EFalse;
+        }
+    return decision;
+    }	
+
+// -----------------------------------------------------------------------------
+// TMcePreconditionsFactory::CreateL
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions* TMcePreconditionsFactory::CreateL( 
+    CMceComMediaStream& aMediaStream,
+    CSdpMediaField& aMediaLine )
+	{
+	//for decoding
+	//check if there is a=curr:sec
+	MCEMM_DEBUG("TMcePreconditionsFactory::CreateL EntryL")
+	if ( &aMediaLine )
+        {	
+		RPointerArray<CSdpAttributeField>& attributes = aMediaLine.AttributeFields();
+	    
+	    TBool decodedSec = EFalse;
+	    TInt index = 0;
+
+	    for( index = 0; index < attributes.Count(); index++ )
+	        {
+	        CSdpAttributeField* attribute = attributes[ index ];
+	        //decode current status	    
+	        if ( attribute->Attribute().DesC().Match( KMceSipSdpPreconditionCurr) != KErrNotFound )
+	            {
+	            TLex8 attributeValue( attribute->Value() );
+	    	    TPtrC8 token = attributeValue.NextToken();
+		        if ( token == KMceSipSdpSec )
+		    	    {
+		    	    decodedSec = ETrue;
+		       	    }      
+	            }
+	        }
+	        
+	    if ( decodedSec )    
+	    	{
+	    	aMediaStream.Session()->iIsSecureSession = ETrue;
+	    	TMceSecurePreconditions* secPreconditions =
+	        new (ELeave) TMceSecurePreconditions( aMediaStream );
+	    	CleanupStack::PushL( secPreconditions );
+	    	secPreconditions->ConstructL();
+	        CleanupStack::Pop( secPreconditions );
+	        aMediaStream.Session()->Modifier( KMceSecPreconditions ) 
+	        	= KMcePreconditionsE2ESupported;
+	        aMediaStream.Session()->iRemoteSecPreconditionsRequired = ETrue;
+	        MCEMM_DEBUG("return Sec Preconds")
+	        MCEMM_DEBUG("TMcePreconditionsFactory::CreateL ExitL")
+		
+			return secPreconditions;
+	    	}
+		}
+    else if ( aMediaStream.Session()->iClientCryptoSuites.Count() &&
+    		  aMediaStream.Session()->Modifier( KMceSecPreconditions ) 
+    		    == KMcePreconditionsE2ESupported)
+    		
+    	{
+    	//for encoded
+    	TMceSecurePreconditions* secPreconditions =
+        new (ELeave) TMceSecurePreconditions( aMediaStream );
+    	CleanupStack::PushL( secPreconditions );
+    	secPreconditions->ConstructL();
+        CleanupStack::Pop( secPreconditions );
+        MCEMM_DEBUG("for encoding preconds return Sec Preconds")
+	
+	    MCEMM_DEBUG("TMcePreconditionsFactory::CreateL ExitL")
+       	return secPreconditions;
+    	}
+    else
+    	{
+    	//nop
+    	}
+	MCEMM_DEBUG("TMcePreconditionsFactory::CreateL ExitL")
+       
+	return NULL;
+	}
+	
+// -----------------------------------------------------------------------------
+// TMcePreconditionsFactory::CreateL
+// -----------------------------------------------------------------------------
+//
+TMcePreconditions* TMcePreconditionsFactory::CreateL( 
+    CMceComMediaStream& aMediaStream )
+	{
+	//only for segmented precondition	 
+  	TMceSegmentedPreconditions*  preconditions =
+        new (ELeave) TMceSegmentedPreconditions( aMediaStream );
+    CleanupStack::PushL( preconditions );
+    preconditions->ConstructL();
+    preconditions->Reserved();
+    CleanupStack::Pop( preconditions );
+    return preconditions;
+	}