--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsharing/mmshavailability/src/musavadefaultoptionhandler.cpp Thu Dec 17 08:44:37 2009 +0200
@@ -0,0 +1,645 @@
+/*
+* Copyright (c) 2005-2007 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: Provide interface for the client requestin availability class.
+*
+*/
+
+
+#include "musavadefaultoptionhandler.h"
+#include "musavasharedobject.h"
+#include "muslogger.h"
+#include "musavasip.h"
+#include "musavasettingsimp.h"
+#include "sipservertransaction.h"
+#include "mussettings.h"
+#include "musavacapability.h"
+#include "musavacapabilitycontext.h"
+#include "musavanetworkmodestatus.h"
+#include <sipstrings.h>
+#include <siptransactionbase.h>
+#include <sipheaderbase.h>
+#include <sipservertransaction.h>
+#include <sipcontenttypeheader.h>
+#include <sdpcodecstringpool.h>
+#include <sipresponseelements.h>
+#include <siprequestelements.h>
+#include <sipmessageelements.h>
+#include <sipconnection.h>
+#include <sipcontactheader.h>
+#include <sdpdocument.h>
+#include <sdpattributefield.h>
+#include <sdpmediafield.h>
+#include <sdpconnectionfield.h>
+#include <sdporiginfield.h>
+#include <sdprtpmapvalue.h>
+#include <sdpfmtattributefield.h>
+#include <e32math.h>
+#include <uriutils.h>
+
+
+const TInt KMaxNumAsStringSize = 16;
+_LIT8( KMUSAVAOriginFieldUser, "-");
+
+
+// --------------------------------------------------------------------------
+// Symbian two-phase constructor
+// --------------------------------------------------------------------------
+//
+CMusAvaDefaultOptionHandler* CMusAvaDefaultOptionHandler::NewL(
+ MMusAvaAvailabilityObserver& aObserver,
+ CMusAvaSettingsImp& aConcreteSettings )
+ {
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::NewL()" )
+ CMusAvaDefaultOptionHandler* self = CMusAvaDefaultOptionHandler::NewLC(
+ aObserver,
+ aConcreteSettings );
+ CleanupStack::Pop( self );
+
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::NewL()" )
+ return self;
+ }
+
+
+// -------------------------------------------------------------------------
+// Two-phased constructor.
+// -------------------------------------------------------------------------
+//
+CMusAvaDefaultOptionHandler* CMusAvaDefaultOptionHandler::NewLC(
+ MMusAvaAvailabilityObserver& aObserver,
+ CMusAvaSettingsImp& aConcreteSettings )
+ {
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::NewLC()" )
+ CMusAvaDefaultOptionHandler* self = new( ELeave )
+ CMusAvaDefaultOptionHandler( aObserver, aConcreteSettings );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::NewLC()" )
+ return self;
+ }
+
+
+// -------------------------------------------------------------------------
+// Constructor.
+// -------------------------------------------------------------------------
+//
+CMusAvaDefaultOptionHandler::CMusAvaDefaultOptionHandler(
+ MMusAvaAvailabilityObserver& aObserver,
+ CMusAvaSettingsImp& aConcreteSettings )
+ :CMusAvaAvailability( aObserver ),
+ iSettings( aConcreteSettings )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CMusAvaDefaultOptionHandler::ConstructL()
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::ConstructL()" )
+ iSharedObj = CMusAvaSharedObject::GetSingletonL();
+ iSharedObj->MusAvaSip().AddAdapterL(
+ ( MMusAvaSipConnectionAdapter& ) *this );
+ iSharedObj->MusAvaSip().AddAdapterL( ( MMusAvaSipAdapter& ) *this );
+ SIPStrings::OpenL();
+ SdpCodecStringPool::OpenL();
+ iOperatorVariant = MultimediaSharingSettings::OperatorVariantSettingL();
+ // set this only for static availability modules
+ iState = MMusAvaObserver::EMusAvaStatusAvailable ;
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::ConstructL()" )
+ }
+
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CMusAvaDefaultOptionHandler::~CMusAvaDefaultOptionHandler()
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::\
+ ~CMusAvaDefaultOptionHandler()" )
+
+ if ( iSharedObj )
+ {
+ iSharedObj->DeleteSingleton();
+ }
+ SIPStrings::Close();
+ SdpCodecStringPool::Close();
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::\
+ ~CMusAvaDefaultOptionHandler()" )
+ }
+
+
+// ---------------------------------------------------------------------------
+// A SIP request outside a dialog has been received from the network.
+// ---------------------------------------------------------------------------
+//
+TInt CMusAvaDefaultOptionHandler::IncomingRequest(
+ CSIPServerTransaction* aTransaction )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::\
+ IncomingRequest()" )
+ TInt err = KErrNotFound;
+ if( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EOptions )
+ //&& !Available( MMusAvaObserver::EMusAvaOptionHandler )
+ )
+ {
+ TRAP( err, IncomingOptionRequestL( aTransaction ) )
+ if( !err )
+ {
+ delete aTransaction;
+ }
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] Not OPTIONS request or not handled in defaultOptionHandler" )
+ }
+
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::\
+ IncomingRequest()" )
+ return err;
+ }
+
+
+
+
+// ---------------------------------------------------------------------------
+// Starts the loopy execution.
+// ---------------------------------------------------------------------------
+//
+void CMusAvaDefaultOptionHandler::DoExecuteL()
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::\
+ ExecutePatternL()" )
+ // set status available
+ SetState( MMusAvaObserver::EMusAvaStatusAvailable );
+
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::\
+ ExecutePatternL()" )
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::Name
+//
+// ---------------------------------------------------------------------------
+//
+MMusAvaObserver::TAvailabilityName CMusAvaDefaultOptionHandler::Name()
+ {
+ MUS_LOG( "mus: [MUSAVA] CMusAvaDefaultOptionHandler::Name()" )
+ return MMusAvaObserver::EMusAvaDefaultOptionHandler;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::IncomingRequest
+//
+// ---------------------------------------------------------------------------
+//
+TInt CMusAvaDefaultOptionHandler::IncomingRequest(
+ TUint32 aIapId,
+ CSIPServerTransaction* aTransaction )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::\
+ IncomingRequest()" )
+ MUS_LOG1( "mus: [MUSAVA] Iap ( %d )", aIapId )
+ TInt err = KErrNotFound;
+ CSIPConnection* connection = NULL;
+ if( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EOptions )
+ && !Available( MMusAvaObserver::EMusAvaOptionHandler ) )
+ {
+ MUS_LOG( "mus: [MUSAVA] create CSIPConnection" )
+ TRAP( err, connection = CSIPConnection::NewL(
+ iSharedObj->MusAvaSip().Sip(),
+ aIapId,
+ iSharedObj->MusAvaSip().ConnectionObserver() ) );
+
+ if( err != KErrNone )
+ {
+ MUS_LOG1( "mus: [MUSAVA] CSIPConnection error ( %d )", err )
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] create CSIPConnection" )
+ TRAP_IGNORE( IncomingOptionRequestL ( aTransaction ) )
+ delete connection;
+ delete aTransaction;
+ }
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] Not OPTIONS request or not handled in defaultOptionHandler" )
+ }
+
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::\
+ IncomingRequest()" )
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::TimedOut
+//
+// ---------------------------------------------------------------------------
+//
+TInt CMusAvaDefaultOptionHandler::TimedOut(CSIPServerTransaction&
+ /*aTransaction*/ )
+ {
+ MUS_LOG( "mus: [MUSAVA] CMusAvaDefaultOptionHandler::ConstructL()" )
+ return KErrNotSupported;
+ }
+
+
+// -------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::IncomingOptionRequestL
+//
+// -------------------------------------------------------------------------
+//
+void CMusAvaDefaultOptionHandler::IncomingOptionRequestL(
+ CSIPServerTransaction* aTransaction )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::\
+ IncomingOptionRequestL()" )
+
+ MusSettingsKeys::TActivation activation =
+ MultimediaSharingSettings::ActivationSettingL();
+
+ if ( activation == MusSettingsKeys::ENever )
+ {
+ MUS_LOG( "mus: [MUSAVA] Sending 603 Decline" )
+ NoCapabilityResponseL( aTransaction,
+ KMUSAVASIPDecline,
+ SipStrConsts::EPhraseDecline );
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] Sending 480 Temporarily Unavilable" )
+ NoCapabilityResponseL( aTransaction,
+ KMUSAVASIPTemporarilyUnavailable,
+ SipStrConsts::EPhraseTemporarilyNotAvailable );
+ }
+
+ MUS_LOG( "mus: [MUSAVA] <- \
+ CMusAvaDefaultOptionHandler::IncomingOptionRequest()" )
+ }
+
+// ------------------------------------------------------------------------
+// Send Response to reques.
+//
+// ------------------------------------------------------------------------
+void CMusAvaDefaultOptionHandler::ResponseL(
+ CSIPResponseElements* aResponseElements,
+ CSIPServerTransaction* aTransaction )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::ResponseL" )
+
+ if ( ( aTransaction->StateL() == CSIPTransactionBase::ETrying ||
+ aTransaction->StateL() == CSIPTransactionBase::EProceeding ) &&
+ aTransaction->ResponseAllowed() )
+ {
+ aTransaction->SendResponseL( aResponseElements );
+ MUS_LOG( " Send response" )
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::ResponseL" )
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] Not allow to sent response " )
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::ResponseL" )
+ User::Leave( KErrNotReady );
+ }
+ }
+
+
+// ------------------------------------------------------------------------
+// Send response to request.
+//
+// ------------------------------------------------------------------------
+void CMusAvaDefaultOptionHandler::NoCapabilityResponseL(
+ CSIPServerTransaction* aTransaction,
+ TUint aStatusCode,
+ SipStrConsts::TStrings aReason )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::SendResponseL()" )
+ MUS_LOG( "mus: [MUSAVA] Create response elements " )
+ CSIPResponseElements* respElem = NULL;
+
+ if( iOperatorVariant == MusSettingsKeys::EOperatorSpecific )
+ {
+ MUS_LOG( "mus: [MUSAVA] Operator Specific response" )
+ respElem = CreateResponseL( *aTransaction );
+ CleanupStack::PushL( respElem );
+ }
+ else
+ {
+ MUS_LOG( "mus: [MUSAVA] Standard response" )
+ RStringF reasonPhrase =
+ SIPStrings::StringF( aReason );
+ respElem =
+ CSIPResponseElements::NewLC( aStatusCode, reasonPhrase );
+ }
+
+ ResponseL( respElem, aTransaction );
+ MUS_LOG( "mus: [MUSAVA] Response sent " )
+ CleanupStack::Pop( respElem );
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::SendResponseL()" )
+ }
+
+
+// ------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::CreateResponseL
+//
+// ----------------------------------------------------------------------------
+//
+CSIPResponseElements* CMusAvaDefaultOptionHandler::CreateResponseL(
+ CSIPServerTransaction& aTransaction )
+ {
+ HBufC8* sdpBody = NULL;
+ CSIPResponseElements* respElem =
+ CSIPResponseElements::NewLC( KMUSAVASIP200,
+ SIPStrings::StringF(SipStrConsts::EPhraseOk) );
+
+ RPointerArray<CSIPHeaderBase> responseHeaders;
+ CSIPHeaderBase::PushLC( &responseHeaders );
+
+ const CUri8& uri = aTransaction.RequestElements()->RemoteUri();
+ CSIPContactHeader* contact = MusAvaCapabilityContext::ContactHeaderLC(
+ uri, SIPStrings::StringF( SipStrConsts::EEmpty ) );
+ responseHeaders.AppendL( contact );
+ CleanupStack::Pop( contact );
+
+ CSIPMessageElements& messageElements = respElem->MessageElements();
+ messageElements.SetUserHeadersL( responseHeaders );
+ CleanupStack::Pop( &responseHeaders );
+
+ CSIPContentTypeHeader* contenType =
+ CSIPContentTypeHeader::NewLC( SIPStrings::StringF(
+ SipStrConsts::EApplication).DesC(),
+ KMUSAVASIPMediaSubTypeSDP );
+
+ // Set content
+ CSdpDocument* sdpDocument = CreateSDPL( aTransaction );
+ CleanupStack::PushL( sdpDocument );
+ sdpBody = ToTextL( *sdpDocument );
+ CleanupStack::PopAndDestroy( sdpDocument );
+ CleanupStack::PushL( sdpBody );
+ messageElements.SetContentL( sdpBody, contenType );
+ CleanupStack::Pop( sdpBody );
+ CleanupStack::Pop( contenType );
+ CleanupStack::Pop( respElem );
+ return respElem;
+ }
+
+
+// ------------------------------------------------------------------------
+// Create SDP response.
+//
+// ------------------------------------------------------------------------
+CSdpDocument* CMusAvaDefaultOptionHandler::CreateSDPL(
+ CSIPServerTransaction& aTransaction )
+ {
+ MUS_LOG( "mus: [MUSAVA] -> CMusAvaDefaultOptionHandler::CreateSDPL" )
+ // Origin field
+ TPtrC8 localHost;
+ RStringF hostType;
+ RStringF netType = SDPStringL( SdpCodecStringConstants::ENetType );
+ CSdpDocument* sdpDocument = CSdpDocument::NewLC();
+ LocalHostL( aTransaction,localHost,hostType);
+ CSdpOriginField* originField = CreateOriginFieldL(localHost,hostType);
+ sdpDocument->SetOriginField(originField);
+ // Connection field
+ CSdpConnectionField* connectionField =
+ CSdpConnectionField::NewL( netType, hostType, localHost );
+ sdpDocument->SetConnectionField( connectionField );
+
+ MUS_LOG( "mus: [MUSAVA] Adding application attribute to SDP" )
+ //application
+ CSdpAttributeField* application =
+ CSdpAttributeField::NewLC(
+ SDPStringL( SdpCodecStringConstants::EMediaApplication ),
+ KCapabilitySwisApplication );
+
+ sdpDocument->AttributeFields().AppendL( application );
+ CleanupStack::Pop( application );
+
+ MUS_LOG( "mus: [MUSAVA] Adding type attribute to SDP" )
+ //type
+ RStringF typeStr = SDPStringL( KCapabilitySDPAttributeNameType );
+ CleanupClosePushL( typeStr );
+ CSdpAttributeField* type =
+ CSdpAttributeField::NewL( typeStr, KCapabilitySDPAttributeType );
+ CleanupStack::PopAndDestroy();//typeStr
+ CleanupStack::PushL( type );
+
+ sdpDocument->AttributeFields().AppendL( type );
+ CleanupStack::Pop( type );
+
+
+ MUS_LOG( "mus: [MUSAVA] Adding media line to SDP" )
+ //media line
+ CSdpMediaField* mediaLine =
+ MediaLineLC( SDPStringL( SdpCodecStringConstants::EMediaVideo ),
+ KCapabilitySwisFormatList );
+
+ //rtpmap
+ MUS_LOG( "mus: [MUSAVA] Adding rtpmap to SDP" )
+ //adding H.264 codec to SDP
+ CSdpFmtAttributeField* rtpMapH264 =
+ RtpMapLineLC( KCapabilitySDPAttributeCodecH264,
+ KCapabilitySDPAttributePayloadTypeH264,
+ KCapabilitySDPAttributeClockrate );
+
+ mediaLine->FormatAttributeFields().AppendL( rtpMapH264 );
+ CleanupStack::Pop( rtpMapH264 );
+
+ //H.263 codec
+ CSdpFmtAttributeField* rtpMapH263 = RtpMapLineLC(
+ KCapabilitySDPAttributeCodecH263,
+ KCapabilitySDPAttributePayloadType,
+ KCapabilitySDPAttributeClockrate );
+
+ mediaLine->FormatAttributeFields().AppendL( rtpMapH263 );
+ CleanupStack::Pop( rtpMapH263 );
+
+ sdpDocument->MediaFields().AppendL( mediaLine );
+ CleanupStack::Pop( mediaLine );
+ CleanupStack::Pop( sdpDocument );
+ MUS_LOG( "mus: [MUSAVA] <- CMusAvaDefaultOptionHandler::CreateSDPL" )
+ return sdpDocument;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::CreateOriginFieldL
+//
+// ----------------------------------------------------------------------------
+//
+CSdpOriginField* CMusAvaDefaultOptionHandler::CreateOriginFieldL(
+ const TDesC8& aLocalHost,
+ const RStringF& aHostType) const
+ {
+ #ifdef UNIT_TESTING
+ TInt64 sessionID = 452027953;
+#else
+ TTime now;
+ now.UniversalTime();
+ TInt64 rand = now.Int64();
+ TInt64 sessionID = Math::Rand( rand );
+#endif
+
+ return CSdpOriginField::NewL(
+ KMUSAVAOriginFieldUser,
+ sessionID,
+ sessionID,
+ SDPStringL( SdpCodecStringConstants::ENetType ),
+ aHostType,
+ aLocalHost);
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::LocalHostL
+//
+// ----------------------------------------------------------------------------
+//
+void CMusAvaDefaultOptionHandler::LocalHostL(
+ const CSIPServerTransaction& aRequest,
+ TPtrC8& aLocalHost,
+ RStringF& aHostType )
+ {
+ RStringPool strPool = SdpCodecStringPool::StringPoolL();
+
+ const CUri8& uri = aRequest.RequestElements()->RemoteUri();
+
+ aLocalHost.Set( uri.Uri().Extract( EUriHost ) );
+
+ if ( UriUtils::HostType( aLocalHost ) == UriUtils::EIPv6Host )
+ {
+ aHostType = strPool.StringF( SdpCodecStringConstants::EAddressType,
+ SdpCodecStringPool::StringTableL() );
+ }
+ else
+ {
+ aHostType = strPool.StringF(
+ SdpCodecStringConstants::EAddressTypeIP4,
+ SdpCodecStringPool::StringTableL() );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::SDPStringL
+//
+// ----------------------------------------------------------------------------
+//
+RStringF CMusAvaDefaultOptionHandler::SDPStringL( const TDesC8& aString )
+ {
+ return SdpCodecStringPool::StringPoolL().OpenFStringL( aString );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::SDPStringL
+//
+// ----------------------------------------------------------------------------
+//
+RStringF CMusAvaDefaultOptionHandler::SDPStringL( TInt aStringIndex )
+ {
+ return SdpCodecStringPool::StringPoolL().
+ StringF( aStringIndex, SdpCodecStringPool::StringTableL() );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::MediaLineLC
+//
+// -----------------------------------------------------------------------------
+//
+CSdpMediaField* CMusAvaDefaultOptionHandler::MediaLineLC(
+ const RStringF& aMedia,
+ const TDesC8& aFormatList ) const
+ {
+ return CSdpMediaField::NewLC( aMedia,
+ NULL,
+ SDPStringL(
+ SdpCodecStringConstants::EProtocolRtpAvp ),
+ aFormatList );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::RtpMapLineLC
+//
+// ----------------------------------------------------------------------------
+//
+CSdpFmtAttributeField* CMusAvaDefaultOptionHandler::RtpMapLineLC(
+ const TDesC8& aCodec,
+ const TUint64 aPayloadType,
+ const TUint64 aClockRate,
+ const TDesC8& aParams ) const
+ {
+ HBufC8* clockrate = HBufC8::NewLC( KMaxNumAsStringSize );
+ clockrate->Des().Num( aClockRate, EDecimal );
+ HBufC8* payload = HBufC8::NewLC( KMaxNumAsStringSize );
+ payload->Des().Num( aPayloadType, EDecimal );
+
+
+ TSdpRtpmapValue rtpmapValue( aCodec,
+ *clockrate,
+ aParams );
+
+
+ HBufC8* rtpmap = rtpmapValue.EncodeL();
+ CleanupStack::PushL( rtpmap );
+
+ CSdpFmtAttributeField* rtpmapAttribute =
+ CSdpFmtAttributeField::NewL( SDPStringL(
+ SdpCodecStringConstants::EAttributeRtpmap ),
+ *payload,
+ *rtpmap );
+
+ CleanupStack::PopAndDestroy( rtpmap );
+ CleanupStack::PopAndDestroy( payload );
+ CleanupStack::PopAndDestroy( clockrate );
+
+ CleanupStack::PushL( rtpmapAttribute );
+
+ return rtpmapAttribute;
+ }
+
+
+// --------------------------------------------------------------------------
+// CMusAvaDefaultOptionHandler::ToTextL
+//
+// --------------------------------------------------------------------------
+//
+HBufC8* CMusAvaDefaultOptionHandler::ToTextL( CSdpDocument& aSdpContent )
+ {
+ HBufC8* content = NULL;
+
+ CBufFlat* encBuf = CBufFlat::NewL( KMUSAVAMaxLengthOfSDPMessage );
+ CleanupStack::PushL( encBuf );
+ RBufWriteStream writeStream( *encBuf, 0 );
+ writeStream.PushL();
+ writeStream.Open( *encBuf, 0 );
+ aSdpContent.EncodeL( writeStream );
+ writeStream.Close();
+ CleanupStack::PopAndDestroy();//writeStream
+
+ content = encBuf->Ptr( 0 ).AllocL();
+ CleanupStack::PopAndDestroy( encBuf );
+
+ return content;
+ }