/*
* Copyright (c) 2008 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 <e32base.h>
#include <e32std.h>
#include <sdporiginfield.h>
#include <sdpconnectionfield.h>
#include <sdpfmtattributefield.h>
#include <sdpmediafield.h>
#include <sdpattributefield.h>
#include <sdpcodecstringpool.h>
#include <sdpdocument.h>
#include <sdpbandwidthfield.h>
#include <siptoheader.h>
#include "mcemediadefs.h"
#include "mcesdpsession.h"
#include "mcecomsession.h"
#include "mcecommediastream.h"
#include "mcemediastream.h"
#include "mcesdpcodec.h"
#include "mcemediamanager.h"
#include "mcemediadefs.h"
#include "mcesrvlogs.h"
#include "mcemmlogs.h"
#include "mcepreconditions.h"
#include "mcemediaobserver.h"
#include "mcemediastate.h"
_LIT8(KTBCP, "TBCP");
// ================= MEMBER FUNCTIONS ==========================================
// -----------------------------------------------------------------------------
// CMceSdpSession::NewL
// -----------------------------------------------------------------------------
//
CMceSdpSession* CMceSdpSession::NewL(
CMceComSession& aSession,
CMceMediaManager& aManager )
{
CMceSdpSession* self = NewLC( aSession, aManager );
CleanupStack::Pop( self );
return self;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::NewLC
// -----------------------------------------------------------------------------
CMceSdpSession* CMceSdpSession::NewLC(
CMceComSession& aSession,
CMceMediaManager& aManager )
{
CMceSdpSession* self = new ( ELeave ) CMceSdpSession( aSession, aManager );
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CMceSdpSession
// -----------------------------------------------------------------------------
//
CMceSdpSession::CMceSdpSession(
CMceComSession& aSession,
CMceMediaManager& aManager )
: iManager( aManager ),
iSessionId( 0 ),
iSessionVersion( 0 ),
iSession( &aSession ),
iStringTable( NULL ),
iOOldSchool( 0 ),
iIOldSchool( 0 ),
iOOldSchoolProceeding( 0 ),
iOOldSchoolCompleted( 0 ),
iIsMaster( ETrue ),
iOldLocalMediaPort( 0 )
{
iSessionId = GetRandomNumber();
iSessionVersion = GetRandomNumber();
iIsSignallingRequired = KMceNoSignalling;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ConstructL
// -----------------------------------------------------------------------------
void CMceSdpSession::ConstructL()
{
SetUserNameL(KMceSdpDefaultUserName);
SetSessionNameL(KMceSdpDefaultSessionName);
iStringPool = SdpCodecStringPool::StringPoolL();
iStringTable = &SdpCodecStringPool::StringTableL();
}
// -----------------------------------------------------------------------------
// CMceSdpSession::~CMceSdpSession
// -----------------------------------------------------------------------------
//
CMceSdpSession::~CMceSdpSession()
{
delete iInitialSession;
delete iSessionName;
delete iUserName;
delete iRemoteOrigin;
iSdpRemoteMediaFields.ResetAndDestroy();
if ( MediaSession() )
{
MediaSession()->DetachSDPSession();
}
if ( Backup() )
{
Backup()->DetachSDPSession();
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Manager
// -----------------------------------------------------------------------------
//
CMceMediaManager& CMceSdpSession::Manager() const
{
return iManager;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SignallingRequired
// -----------------------------------------------------------------------------
//
TInt& CMceSdpSession::SignallingRequired()
{
return iIsSignallingRequired;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CreateOfferL
// -----------------------------------------------------------------------------
//
CSdpDocument* CMceSdpSession::CreateOfferL(
CMceComSession& aSession,
CMceSdpSession::TOfferType aType )
{
MCEMM_DEBUG("CMceSdpSession::CreateOfferL(), Entry ")
CSdpDocument* sdpDocument = NULL;
if ( aType == CMceSdpSession::ERefresh )
{
User::LeaveIfNull( iSdpDocument );
EncodeSessionParamsL( aSession, *iSdpDocument, aType );
if(iOldLocalMediaPort != iSdpDocument->MediaFields()[0]->Port())
{
iSdpDocument->MediaFields()[0]->SetPortL( iOldLocalMediaPort );
}
return iSdpDocument;
}
if ( aType == CMceSdpSession::EFirst )
{
sdpDocument = CSdpDocument::NewLC();
}
else
{
sdpDocument = iSdpDocument;
CleanSessionParams( *iSdpDocument );
}
EncodeSessionParamsL( aSession, *sdpDocument, aType );
EncodeClientAttributesL( aSession, *sdpDocument );
//create offer based on receive, receive only or send stream
RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
RPointerArray< CSdpMediaField >& mediaLines = sdpDocument->MediaFields();
CSdpMediaField* mediaLine = NULL;
CMceSdpCodec* sdpCodec = NULL;
CMceComMediaStream* mediastream = NULL;
if ( aSession.iPullModeUpdate && aType == CMceSdpSession::EUpdate )
{
// matching the streams to media lines in Pull mode update case
MatchingStreamsToMLinesL( *sdpDocument, aSession );
}
for ( TInt index = 0; index < streams.Count(); index++ )
{
mediastream = streams[ index ];
TBool add = MediaLineLC( mediaLine, sdpCodec, mediastream,
mediaLines, streams );
if ( mediaLine )
{
if (!add)
{
mediaLine->SetPortL( mediastream->iLocalMediaPort );
}
mediastream = mediastream->OfferStream();//downlink
sdpCodec->PrepareForEncodeL( *mediastream, *mediaLine );
sdpCodec->EncodeMediaOfferL( *mediastream, *mediaLine, *sdpDocument );
if ( add )
{
mediaLines.AppendL( mediaLine );
CleanupStack::Pop( mediaLine );
mediastream->SdpIndex() = mediaLines.Count() - 1;
}
}
}
User::LeaveIfError( sdpDocument->IsValid() );
if ( aType == CMceSdpSession::EFirst )
{
CleanupStack::Pop( sdpDocument );
}
iOldLocalMediaPort = sdpDocument->MediaFields()[0]->Port();
MCEMM_DEBUG("CMceSdpSession::CreateOfferL(), Exit ")
return sdpDocument;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::MatchingStreamsAndMLinesL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::MatchingStreamsToMLinesL(
CSdpDocument& aSdpDocument,
CMceComSession& aSession )
{
MCEMM_DEBUG("CMceSdpSession::MatchingStreamsToMLinesL(),entry ")
//create offer based on receive, receive only or send stream
RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
RPointerArray< CSdpMediaField >& mediaLines = aSdpDocument.MediaFields();
// set SDPindex for stream if related meida line is found
for ( TInt index = 0; index < streams.Count(); index++ )
{
CMceComMediaStream* mediastream = streams[ index ];
CMceSdpCodec* sdpCodecStream = NULL;
sdpCodecStream = Manager().SdpCodec( *mediastream );
if ( sdpCodecStream )
{
TInt mediaIndex = 0;
while( mediaIndex < mediaLines.Count() )
{
CSdpMediaField* mediaLine = mediaLines[ mediaIndex ];
CMceSdpCodec* sdpCodecMediaLine = NULL;
sdpCodecMediaLine = Manager().SdpCodec( *mediaLine );
if ( sdpCodecMediaLine && sdpCodecMediaLine->Media() == sdpCodecStream->Media() )
{
mediastream->SdpIndex() = mediaIndex;
}
mediaIndex++;
}
}
MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), stream index:", index )
MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), stream SdpIndex:",
mediastream->SdpIndex() )
}
// set port to 0 if there are unused media lines
for ( TInt index = 0; index < mediaLines.Count(); index++ )
{
// set old session media lines port to 0
CSdpMediaField* mediaLine = mediaLines[ index ];
TBool indexFoundFromStream = EFalse;
TInt streamIndex = 0;
while( !indexFoundFromStream && streamIndex < streams.Count() )
{
CMceComMediaStream* mediastream = streams[ streamIndex ];
if ( index == mediastream->SdpIndex() )
{
indexFoundFromStream = ETrue;
}
streamIndex++;
}
if ( !indexFoundFromStream )
{
MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), \
set media line to 0, index:", index )
mediaLine->SetPortL( 0 );
}
}
MCEMM_DEBUG("CMceSdpSession::MatchingStreamsToMLinesL(),exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DecodeAnswerL
// -----------------------------------------------------------------------------
//
TInt CMceSdpSession::DecodeAnswerL(
CSdpDocument& aSdpDocument,
CMceComSession& aSession )
{
MCEMM_DEBUG("CMceSdpSession::DecodeAnswerL(), Entry ")
iSdpDocument = &aSdpDocument;
RPointerArray< CSdpMediaField >& mediaLines = iSdpDocument->MediaFields();
if ( mediaLines.Count() == 0 )
{
User::Leave( KErrArgument );
}
// store the remote o= field
StoreRemoteOriginL();
// store the remote a= field
StoreRemoteMediaFieldsL();
TInt err = SetRemoteIpAddressL( aSession, aSdpDocument );
if ( err != KErrNone )
{
MCEMM_DEBUG("ERROR: Incompatible network address")
User::Leave( KErrArgument );
}
// handle media lines
RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
CSdpMediaField* mediaLine = NULL;
CMceSdpCodec* sdpCodec = NULL;
CMceComMediaStream* mediastream = NULL;
TInt index = 0;
// Go through the answer's media lines. If there is a line for which there
// is no stream (remote has put wrong port to answer), set port to zero.
// Do this before the second for-loop, as DecodeMediaAnswerL may leave with
// KMceErrOldSchool, starting old school hold. In that case any further
// media lines would not be processed and if they had wrong port (non-zero
// port but no media stream), we'd use that in our next offer.
if ( !aSession.iPullModeUpdate )
{
for ( index = 0; index < mediaLines.Count(); index++ )
{
mediaLine = mediaLines[ index ];
if ( Manager().SdpCodec( *mediaLine ) &&
!MediaSlotInUse( index, streams ) )
{
mediaLine->SetPortL( 0 );
}
}
}
for ( index = 0; index < mediaLines.Count(); index++ )
{
mediaLine = mediaLines[ index ];
sdpCodec = Manager().SdpCodec( *mediaLine );
if ( sdpCodec )
{
if ( !aSession.iPullModeUpdate )
{
TUint remotePort = mediaLine->Port();
aSession.iRemoteIpAddress.SetPort( remotePort );
mediastream = MediaSlotInUse( index, streams );
// Check for local Support of media and only decode media
// which we support or in use
if ( mediastream )
{
mediastream = mediastream->AnswerStream();//uplink
__ASSERT_ALWAYS( mediastream , User::Leave( KErrArgument ) );
mediastream->SetRemoteMediaPort( remotePort );
if ( remotePort )
{
TInt warnings = KErrNone;
sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
warnings = sdpCodec->DecodeMediaAnswerL( *mediaLine,
*mediastream,
aSdpDocument );
if ( warnings >= KMceSipBadRequest)
{
return warnings;
}
mediastream->DecodedL( KMceRoleOfferer );
}
else //rejected
{
mediastream->SetDirection( SdpCodecStringConstants::EAttributeInactive );
mediastream->SdpIndex() = KErrNotFound;
}
}
}
else
{
DecodePullModeUpdateMediaLineL(
aSdpDocument, aSession, *mediaLine, index, *sdpCodec );
}
}
else
{
MCEMM_DEBUG_SVALUE("No SDP codec. m-line", mediaLine->Media().DesC() )
}
}
//check that all answers to offers were received
User::LeaveIfError( MediaSlotInUse( index, streams ) ? KErrArgument : KErrNone );
// set the o= field with the local information
EncodeSessionParamsL( aSession, *iSdpDocument );
// store session level attributes
DecodeClientAttributesL( aSdpDocument, aSession );
MCEMM_DEBUG("CMceSdpSession::DecodeAnswerL(), Exit ")
return KErrNone;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DecodePullModeUpdateMediaLineL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::DecodePullModeUpdateMediaLineL(
CSdpDocument& aSdpDocument,
CMceComSession& aSession,
CSdpMediaField& aMediaLine,
TInt aIndex,
CMceSdpCodec& aSdpCodec )
{
MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), Entry ")
RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
CMceComMediaStream* mediastream = NULL;
TUint remotePort = aMediaLine.Port();
aSession.iRemoteIpAddress.SetPort( remotePort );
// this media line might be from previous session, and it's
// port is 0, if so mediastream can't be found
mediastream = MediaSlotInUse( aIndex, streams );
MCEMM_DEBUG_DVALUE( "CMceSdpSession::DecodePullModeUpdateMediaLineL, remotePort:",
remotePort )
if ( mediastream )
{
MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), stream found ")
mediastream = mediastream->AnswerStream();//uplink
__ASSERT_ALWAYS( mediastream , User::Leave( KErrArgument ) );
mediastream->SetRemoteMediaPort( remotePort );
if ( remotePort )
{
aSdpCodec.PrepareForDecodeL( aMediaLine, mediastream );
aSdpCodec.DecodeMediaAnswerL( aMediaLine, *mediastream, aSdpDocument );
mediastream->DecodedL( KMceRoleOfferer );
}
else
{
mediastream->SetDirection( SdpCodecStringConstants::EAttributeInactive );
mediastream->SdpIndex() = KErrNotFound;
}
}
// if streams not found and port in meida line is not 0
// leave with KErrNotFound
User::LeaveIfError( (!mediastream && remotePort) ? KErrNotFound : KErrNone );
MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DecodeOfferL
// -----------------------------------------------------------------------------
//
TInt CMceSdpSession::DecodeOfferL(
CSdpDocument& aSdpDocument,
CMceComSession& aSession )
{
MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Entry ")
TInt result = KErrNone;
iSdpDocument = &aSdpDocument;
RPointerArray <CSdpMediaField>& mediaLines = iSdpDocument->MediaFields();
if ( mediaLines.Count() == 0 )
{
MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), ERROR: No media lines")
MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Exit ")
return KMceSipWarnIncompatibleMediaFormat;
}
// store the remote o= field
StoreRemoteOriginL();
// store the remote a= field
StoreRemoteMediaFieldsL();
//set remote ip address
result = SetRemoteIpAddressL( aSession, aSdpDocument );
if ( result != KErrNone )
{
MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), ERROR: Incompatible network address")
MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Exit ")
return result;
}
DecodeConnectionFieldL( *iSdpDocument, aSession );
// handle media lines
RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
CSdpMediaField* mediaLine = NULL;
CMceSdpCodec* sdpCodec = NULL;
CMceComMediaStream* mediastream = NULL;
TInt streamCount( 0 );
for ( TInt i = 0; i < streams.Count(); i++ )
{
if ( streams[ i ]->iStreamType != CMceComMediaStream::ELocalStream )
{
streamCount++;
}
}
if ( streamCount > mediaLines.Count() )
{
return KMceSipNotAcceptableHere;
}
TInt index = 0;
while( index < mediaLines.Count() )
{
mediaLine = mediaLines[ index ];
TUint remotePort = mediaLine->Port();
if ( remotePort )
{
sdpCodec = Manager().SdpCodec( *mediaLine );
if ( sdpCodec )
{
TInt warning = KErrNone;
aSession.iRemoteIpAddress.SetPort( remotePort );
mediastream = MediaSlotInUse( index, streams );
if ( !mediastream )
{
sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
warning = sdpCodec->DecodeMediaOfferL( *mediaLine, mediastream,
aSession, aSdpDocument );
}
else
{
//update
mediastream = mediastream->AnswerStream();//uplink
sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
warning = sdpCodec->DecodeMediaUpdateL( *mediaLine, *mediastream,
aSdpDocument );
}
if ( warning >= KMceSipBadRequest )
{
return warning;
}
if ( warning != KErrNone )
{
//media will be rejected when answer is created
if ( mediastream )
{
TInt streamIndex = aSession.Streams().Find( &(*mediastream)() );
__ASSERT_ALWAYS( streamIndex >= 0, User::Leave( KErrArgument ) );
MCEMM_DEBUG_DVALUE("removing stream", streamIndex )
aSession.Streams().Remove( streamIndex );
delete mediastream;
}
}
else
{
__ASSERT_ALWAYS( mediastream, User::Leave( KErrArgument ) );
mediastream->DecodedL( KMceRoleAnswerer );
mediastream->SdpIndex() = index;
}
}
else
{
MCEMM_DEBUG_SVALUE("No SDP codec. m-line", mediaLine->Media().DesC() )
}
}
index++;
}
if( streams.Count() > 0 )
{
// at least one media line successfully decoded and corresponding
// server streams created or inactive media line received
MCEMM_DEBUG("Incoming OFFER successfully decoded")
}
else
{
MCEMM_DEBUG("ERROR: Negotiation failed")
result = KMceSipWarnMediaTypeNotAvailable;
}
if ( result == KErrNone )
{
// store session level attributes
DecodeClientAttributesL( aSdpDocument, aSession );
}
MCEMM_DEBUG_DVALUE("CMceSdpSession::DecodeOfferL(), Exit ", result )
return result;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CreateAnswerL
// -----------------------------------------------------------------------------
//
CSdpDocument& CMceSdpSession::CreateAnswerL(
CMceComSession& aSession,
TBool aInvalid )
{
MCEMM_DEBUG("CMceSdpSession::CreateAnswerL(), Entry ")
TOfferType type = !Backup() ? EFirst : EUpdate;
CleanSessionParams( *iSdpDocument );
EncodeSessionParamsL( aSession, *iSdpDocument, type );
EncodeClientAttributesL( aSession, *iSdpDocument );
RPointerArray <CSdpMediaField>& mediaLines = iSdpDocument->MediaFields();
__ASSERT_ALWAYS( mediaLines.Count() > 0, User::Leave( KErrArgument ) );
RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
CSdpMediaField* mediaLine = NULL;
CMceSdpCodec* sdpCodec = NULL;
CMceComMediaStream* mediastream = NULL;
TInt index = 0;
if ( !aInvalid )
{
for ( index = 0; index < streams.Count(); index++ )
{
mediastream = streams[ index ];
TBool add = MediaLineLC( mediaLine, sdpCodec, mediastream,
mediaLines, streams );
User::LeaveIfError( add ? KErrNotFound : KErrNone );
if ( mediaLine )
{
mediastream = mediastream->OfferStream();//downlink
sdpCodec->PrepareForEncodeL( *mediastream, *mediaLine );
PrepareForAnswerEncodeL( *mediaLine );
sdpCodec->EncodeMediaAnswerL( *mediastream, *mediaLine, *iSdpDocument );
}
}
//reject removed streams
//ignore the Supported File Stream will be handled by other plugin
for ( index = 0; index < mediaLines.Count(); index++ )
{
mediaLine = mediaLines[ index ];
sdpCodec = Manager().SdpCodec( *mediaLine );
if ( sdpCodec || mediaLine->FormatList() != KTBCP )
{
if ( !MediaSlotInUse( index, streams ) )
{
MCEMM_DEBUG_SVALUE("Rejecting media line", mediaLine->Media().DesC() )
mediaLines[ index ]->RejectMedia();
}
}
}
MCEMM_DEBUG("Negotiation successful! Answer created ")
}
else
{
MCEMM_DEBUG("Negotiation failed! Reject all media lines ")
// negotiation failed, reject all media lines in the offer
for (index = 0; index < mediaLines.Count(); index++)
{
mediaLines[ index ]->RejectMedia();
}
}
User::LeaveIfError( iSdpDocument->IsValid() );
iOldLocalMediaPort = iSdpDocument->MediaFields()[0]->Port();
MCEMM_DEBUG("CMceSdpSession::CreateAnswerL(), Exit ")
return *iSdpDocument;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::PrepareForAnswerEncodeL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::PrepareForAnswerEncodeL( CSdpMediaField& aMediaLine )
{
TLex8 formats( aMediaLine.FormatList() );
while( !formats.Eos() )
{
TPtrC8 format = formats.NextToken();
aMediaLine.RemoveFormatL( format );
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CreateMediaLineLC
// -----------------------------------------------------------------------------
//
CSdpMediaField* CMceSdpSession::CreateMediaLineLC(
CMceComMediaStream& aStream ) const
{
RStringF protocol = SDP_STRING( SdpCodecStringConstants::EProtocolRtpAvp );
CSdpMediaField* medialine =
CSdpMediaField::NewLC( Manager().SdpCodec( aStream )->Media(),
aStream.iLocalMediaPort,
protocol,
KMceSdpNullFormatList );
return medialine;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::MediaLineLC
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::MediaLineLC(
CSdpMediaField*& aMediaLine,
CMceSdpCodec*& sdpCodec,
CMceComMediaStream* aStream,
RPointerArray<CSdpMediaField>& aMediaLines,
RPointerArray<CMceComMediaStream>& aStreams )
{
//filter out local streams
if ( !aStream ||
!Manager().SdpCodec( *aStream ) )
{
aMediaLine = NULL;
sdpCodec = NULL;
return EFalse;
}
sdpCodec = Manager().SdpCodec( *aStream );
TInt mediaIndex = aStream->SdpIndex();
if ( mediaIndex == KErrNotFound )
{
TInt index = 0;
TBool inUse = ETrue;
while( inUse && index < aMediaLines.Count() )
{
CSdpMediaField* mediaLine = aMediaLines[ index ];
if ( Manager().SdpCodec( *mediaLine ) )
{
inUse = MCE_NOT_NULL_PTR( MediaSlotInUse( index, aStreams ) );
}
mediaIndex = !inUse ? index : mediaIndex;
index++;
}
}
if ( mediaIndex == KErrNotFound )//all in use
{
aMediaLine = CreateMediaLineLC( *aStream );
}
else
{
__ASSERT_ALWAYS( aMediaLines.Count() > mediaIndex , User::Leave( KErrArgument ) );
aMediaLine = aMediaLines[ mediaIndex ];
}
__ASSERT_ALWAYS( Manager().SdpCodec( *aMediaLine ), User::Leave( KErrArgument ) );
return mediaIndex == KErrNotFound;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::MediaSlotInUse
// -----------------------------------------------------------------------------
//
CMceComMediaStream* CMceSdpSession::MediaSlotInUse(
TInt aMediaLine,
RPointerArray<CMceComMediaStream>& aStreams )
{
CMceComMediaStream* stream = NULL;
TInt index = 0;
while( !stream && index < aStreams.Count() )
{
stream = aStreams[ index++ ];
stream = Manager().SdpCodec( *stream ) &&
stream->SdpIndex() == aMediaLine ? stream : NULL;
}
return stream;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CleanSessionParams
// -----------------------------------------------------------------------------
//
void CMceSdpSession::CleanSessionParams( CSdpDocument& aDocument ) const
{
MCEMM_DEBUG("CMceSdpSession::CleanSessionParams()")
aDocument.AttributeFields().ResetAndDestroy();
aDocument.BandwidthFields().ResetAndDestroy();
}
// -----------------------------------------------------------------------------
// CMceSdpSession::EncodeSessionParamsL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::EncodeSessionParamsL(
CMceComSession& aSession,
CSdpDocument& aDocument,
TOfferType aType )
{
MCEMM_DEBUG("CMceSdpSession::EncodeSessionParamsL(), Entry ")
// Set session name: s=
aDocument.SetSessionNameL( *iSessionName );
if( aType == EFirst )
{
// update the name in o= field only when creating intial offer/answer
HBufC8* originator = NULL;
if ( aSession.iType == CMceComSession::EOutSession )
{
originator = aSession.iOriginator;
}
else
{
originator = aSession.iRecipient;
}
if (originator && originator->Length() > 0)
{
CSIPToHeader* to = CSIPToHeader::DecodeL( *originator);
CleanupStack::PushL(to);
const TDesC8& username = to->SIPAddress().Uri8().Uri().Extract( EUriUserinfo );
if ( username.Length() )
{
SetUserNameL( username );
}
else
{
const TDesC8& uripath = to->SIPAddress().Uri8().Uri().Extract( EUriPath );
const TDesC8& uri = to->SIPAddress().Uri8().Uri().UriDes();
if ( uripath.Length() )
{
SetUserNameL( uripath );
}
else
{
SetUserNameL( uri );
}
}
CleanupStack::PopAndDestroy(to);
}
}
else if( aType == EUpdate )
{
iSessionVersion++;
}
CSdpOriginField* originField =
CSdpOriginField::NewL( UserName(),
iSessionId,
iSessionVersion,
aSession.iLocalIpAddress );
aDocument.SetOriginField( originField );
EncodeConnectionFieldL( aSession, aDocument );
MCEMM_DEBUG("CMceSdpSession::EncodeSessionParamsL(), Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SetRemoteIpAddressL
// -----------------------------------------------------------------------------
//
TMceSipWarningCode CMceSdpSession::SetRemoteIpAddressL(
CMceComSession& aSession,
CSdpDocument& aSdpDocument )
{
TMceSipWarningCode result = KErrNone;
RPointerArray< CSdpMediaField >& mediaLines = aSdpDocument.MediaFields();
// get the remote ip address
CSdpConnectionField* connfield = aSdpDocument.ConnectionField();
const TInetAddr* inetAddr = NULL;
if( connfield )
{
inetAddr = connfield->InetAddress();
if( inetAddr )
{
const TInetAddr inetAddress = *(connfield->InetAddress() );
// if present, if not then should be media level
MCE_SET_REMOTE_IP_ADDR( &aSession, inetAddress );
}
}
if ( !inetAddr )
{
TInt index = 0;
TBool found = ETrue;
while( found && index < mediaLines.Count() )
{
RPointerArray<CSdpConnectionField>& connfields =
mediaLines[index]->ConnectionFields();
if ( mediaLines[index++]->Port() > 0 )
{
TInt cfindex = 0;
TBool cffound = EFalse;
while( !cffound && cfindex < connfields.Count() )
{
inetAddr = connfields[cfindex++]->InetAddress();
cffound = MCE_NOT_NULL_PTR( inetAddr );
}
found = cffound;
}
}
}
if ( inetAddr )
{
MCE_SET_REMOTE_IP_ADDR( &aSession, *inetAddr );
}
else
{
result = KMceSipWarnIncompatibleNetworkAddressFormat;
}
return result;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SetSessionNameL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::SetSessionNameL( const TDesC8& aSessionName )
{
HBufC8* tmp = aSessionName.AllocL();
delete iSessionName;
iSessionName = tmp;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SetMediaSession
// -----------------------------------------------------------------------------
//
void CMceSdpSession::SetMediaSession( CMceComSession* aSession )
{
iSession = aSession;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::MediaSession
// -----------------------------------------------------------------------------
//
CMceComSession* CMceSdpSession::MediaSession()
{
return iSession;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SetBackup
// -----------------------------------------------------------------------------
//
void CMceSdpSession::SetBackup( CMceComSession* aSession )
{
iBackup = aSession;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Backup
// -----------------------------------------------------------------------------
//
CMceComSession* CMceSdpSession::Backup()
{
return iBackup;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DetachMedia
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::DetachMedia( CMceComSession& aSession )
{
if ( &aSession == MediaSession() )
{
SetMediaSession( NULL );
}
else if ( &aSession == Backup() )
{
SetBackup( NULL );
}
else
{
return EFalse;
}
return ETrue;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SetUserNameL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::SetUserNameL( const TDesC8& aUserName )
{
HBufC8* tmp = aUserName.AllocL();
delete iUserName;
iUserName = tmp;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::UserName
// -----------------------------------------------------------------------------
//
const TDesC8& CMceSdpSession::UserName() const
{
return *iUserName;
}
// ------------------------------------------------------------------------------
// CMceSdpSession::StoreRemoteOriginL
// ------------------------------------------------------------------------------
//
void CMceSdpSession::StoreRemoteOriginL()
{
CSdpOriginField* origin = iSdpDocument->OriginField();
User::LeaveIfNull( origin );
CSdpOriginField* tmp = origin->CloneL();
delete iRemoteOrigin;
iRemoteOrigin = tmp;
}
// ------------------------------------------------------------------------------
// CMceSdpSession::StoreRemoteMediaFieldsL
// ------------------------------------------------------------------------------
//
void CMceSdpSession::StoreRemoteMediaFieldsL()
{
iSdpRemoteMediaFields.ResetAndDestroy();
for ( TInt i = 0; i < iSdpDocument->MediaFields().Count(); i++ )
{
CSdpMediaField* field = iSdpDocument->MediaFields()[i]->CloneL();
CleanupStack::PushL( field );
iSdpRemoteMediaFields.AppendL( field );
CleanupStack::Pop( field );
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DecodeConnectionFieldL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::DecodeConnectionFieldL(
CSdpDocument& aSdpDocument,
CMceComSession& aSession )
{
CSdpConnectionField* nullAddress =
CSdpConnectionField::DecodeL( KMceSipNullAddressA );
CleanupStack::PushL( nullAddress );
CMceSdpSession& sdpSession = aSession.SdpSession();
CSdpConnectionField* connectionField = aSdpDocument.ConnectionField();
if ( connectionField &&
( connectionField->Address() == nullAddress->Address() ) )
{
sdpSession.iIOldSchool = 1;
}
else
{
sdpSession.iIOldSchool = 0;
}
CleanupStack::PopAndDestroy( nullAddress );
}
// -----------------------------------------------------------------------------
// CMceSdpSession::EncodeConnectionFieldL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::EncodeConnectionFieldL(
CMceComSession& aSession,
CSdpDocument& aSdpDocument )
{
RPointerArray <CSdpMediaField>& mediaLines = aSdpDocument.MediaFields();
TInt mediaLinesIndex = 0;
TBool found = EFalse;
TInt mCLineCount = 0;
while( mediaLinesIndex < mediaLines.Count() )
{
RPointerArray<CSdpConnectionField>& connfields =
mediaLines[mediaLinesIndex++]->ConnectionFields();
TInt connfieldsIndex = 0;
while( connfieldsIndex < connfields.Count() )
{
if ( !connfieldsIndex )
{
mCLineCount++;
}
CSdpConnectionField* connectionField = connfields[connfieldsIndex++];
// if there are media level c= lines, copy the local address
// to be media c= lines
if ( iIOldSchool )
{
connectionField->SetAddressL(
connectionField->NetType(),
connectionField->AddressType(),
KMceSipNullAddress );
}
else
{
connectionField->SetInetAddressL( aSession.iLocalIpAddress );
}
}
// each media line have a media c= line
if ( mCLineCount == mediaLines.Count() )
{
found = ETrue;
}
}
if ( !found || aSdpDocument.ConnectionField() )
{
// rfc4566 5.7 Connection Data ("c="), media level c= lines are more
// important and will override session level c= line if both exists, copy
// the local address to be session level c= line when MO provide it also
CSdpConnectionField* connectionField = NULL;
if ( iIOldSchool )
{
connectionField = CSdpConnectionField::DecodeL( KMceSipNullAddressA );
}
else
{
connectionField = CSdpConnectionField::NewL( aSession.iLocalIpAddress );
}
aSdpDocument.SetConnectionField( connectionField );
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::IsSessionRefresh
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::IsSessionRefresh( CSdpDocument* aSdpDocument )
{
TBool isRefresh = EFalse;
if ( aSdpDocument )
{
iSdpDocument = aSdpDocument;
}
if ( iSdpDocument )
{
CSdpOriginField* origin = iSdpDocument->OriginField();
if( origin && iRemoteOrigin && *iRemoteOrigin == *origin )
{
isRefresh = CompareMediaLines( iSdpRemoteMediaFields,
iSdpDocument->MediaFields() );
}
}
return isRefresh;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::CompareMediaLines
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::CompareMediaLines(
RPointerArray<CSdpMediaField>& aFieldsSrc,
RPointerArray<CSdpMediaField>& aFieldsDst ) const
{
TBool result = EFalse;
TInt srcCount = aFieldsSrc.Count();
TInt dstCount = aFieldsDst.Count();
// Return if count of media fields are not equal.
if ( srcCount == dstCount )
{
result = ETrue;
// Return if every media field from source array
// cannot be found from destination array.
for ( TInt i = 0; i < srcCount && result; i++ )
{
result = EFalse;
for ( TInt j = 0; j < dstCount && !result; j++ )
{
if ( *aFieldsSrc[i] == *aFieldsDst[j] )
{
result = ETrue;
}
}
}
}
return result;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::PrepareSessionRefreshL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::PrepareSessionRefreshL( CMceComSession& aSession )
{
User::LeaveIfNull( iSdpDocument );
EncodeSessionParamsL( aSession, *iSdpDocument );
}
// -----------------------------------------------------------------------------
// CMceSdpSession::SdpCleanup
// -----------------------------------------------------------------------------
//
void CMceSdpSession::SdpCleanup(
CSdpDocument* aPrevious,
CSdpDocument* aReplacement )
{
if ( iSdpDocument && iSdpDocument == aPrevious )
{
MCEMM_DEBUG("CMceSdpSession::SdpCleanup(), replacing")
iSdpDocument = aReplacement;
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::GetRandomNumber
// -----------------------------------------------------------------------------
//
TInt64 CMceSdpSession::GetRandomNumber()
{
TTime currentTime;
currentTime.HomeTime();
TInt64 value( currentTime.Int64() );
return value;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::NeedToNegotiate
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::NeedToNegotiate( CMceComSession& aSession )
{
TBool needToNegotiate = EFalse;
RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
TInt index = 0;
while( !needToNegotiate && index < streams.Count() )
{
CMceComMediaStream* stream = streams[ index++ ];
for( int i = 0; i < stream->Preconditions().Count(); i++ )
{
needToNegotiate = stream->Preconditions().Count() &&
!stream->Preconditions()[i]->IsMet();
}
}
return needToNegotiate;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ReservationNeeded
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::ReservationNeeded( CMceComSession& aSession )
{
TBool reservationNeeded = EFalse;
RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
TInt index = 0;
while( !reservationNeeded && index < streams.Count() )
{
CMceComMediaStream* stream = streams[ index++ ];
for( int i = 0; i < stream->Preconditions().Count(); i++ )
{
reservationNeeded = ( stream->Preconditions().Count() &&
stream->Preconditions()[i]->IsMet() ) ? EFalse : ETrue;
}
}
return reservationNeeded;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ReserveL
// -----------------------------------------------------------------------------
//
TMceReturnStatus CMceSdpSession::ReserveL( CMceComSession& aSession )
{
//fake implementation
TMceReturnStatus status = KMceReady;
RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
TInt index = 0;
while( index < streams.Count() )
{
CMceComMediaStream* stream = streams[ index++ ];
if ( stream->Preconditions().Count() )
{
for( int i = 0; i < stream->Preconditions().Count(); i++ )
{
stream->Preconditions()[ i ]->Reserved();
}
}
}
return status;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::EncodeClientAttributesL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::EncodeClientAttributesL(
CMceComSession& aSession,
CSdpDocument& aDocument ) const
{
MCEMM_DEBUG("CMceSdpSession::EncodeClientAttributesL, Entry ")
CDesC8Array* clientAttributes = aSession.iLocalSessionSDPLines;
__ASSERT_ALWAYS( clientAttributes, User::Leave( KErrArgument ) );
CMceSdpCodec::EncodeClientSdpFieldsL<CSdpDocument>( *clientAttributes, aDocument );
MCEMM_DEBUG("CMceSdpSession::EncodeClientAttributesL, Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::DecodeClientAttributesL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::DecodeClientAttributesL(
CSdpDocument& aDocument,
CMceComSession& aSession ) const
{
MCEMM_DEBUG("CMceSdpSession::DecodeClientAttributesL, Entry ")
CDesC8Array* remoteAttributes =
new (ELeave) CDesC8ArrayFlat( KMceArrayGranularity );
CleanupStack::PushL( remoteAttributes );
CBufFlat* encodeBuf = NULL;
for ( TInt i = 0; i < aDocument.AttributeFields().Count(); i++ )
{
encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
CleanupStack::PushL( encodeBuf );
RBufWriteStream writeStream( *encodeBuf, 0 );
writeStream.PushL();
aDocument.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 < aDocument.BandwidthFields().Count(); i++ )
{
encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
CleanupStack::PushL( encodeBuf );
RBufWriteStream writeStream( *encodeBuf, 0 );
writeStream.PushL();
aDocument.BandwidthFields()[ i ]->EncodeL( writeStream );
MCEMM_DEBUG_SVALUE("found attribute", encodeBuf->Ptr( 0 ) )
remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) );
CleanupStack::PopAndDestroy(); // writeStream
CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf
}
CleanupStack::Pop( remoteAttributes );
MCE_DELETE( aSession.iRemoteSessionSDPLines );
aSession.iRemoteSessionSDPLines = remoteAttributes;
MCEMM_DEBUG("CMceSdpSession::DecodeClientAttributesL, Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Consumes
// -----------------------------------------------------------------------------
//
CMceComSession* CMceSdpSession::Consumes( TUint32 aSessionId )
{
CMceComSession* session = MediaSession();
CMceComSession* backup = Backup();
CMceComSession* foundSession = NULL;
foundSession = ( session &&
session->iMccID != KMceNotAssigned &&
session->iMccID == aSessionId ) ?
session :
( backup &&
backup->iMccID != KMceNotAssigned &&
backup->iMccID == aSessionId ) ?
backup :
NULL;
return foundSession;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::StockMediaSessionL
// -----------------------------------------------------------------------------
//
void CMceSdpSession::StockMediaSessionL()
{
MCEMM_DEBUG("CMceSdpSession::StockMediaSessionL, Entry ")
if ( !iInitialSession && !Backup() )
{
iInitialSession = MediaSession()->CloneL();
MCEMM_DEBUG("Stocked")
}
MCEMM_DEBUG("CMceSdpSession::StockMediaSessionL, Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ForkL
// -----------------------------------------------------------------------------
//
CMceSdpSession& CMceSdpSession::ForkL()
{
MCEMM_DEBUG("CMceSdpSession::ForkL, Entry ")
__ASSERT_ALWAYS( MediaSession(), User::Leave( KErrArgument ) );
__ASSERT_ALWAYS( IsMaster(), User::Leave( KErrArgument ) );
__ASSERT_ALWAYS( !Backup(), User::Leave( KErrArgument ) );
__ASSERT_ALWAYS( iInitialSession, User::Leave( KErrArgument ) );
CMceComSession* forkedMediaSession =
iInitialSession->CloneAndMergeLC( *MediaSession() );
CMceSdpSession& forkedSession = Manager().CreateSessionL( *forkedMediaSession );
ContextSwitch( &forkedSession );
MediaSession()->MediaObserver().SessionCreatedL( forkedMediaSession );
CleanupStack::Pop( forkedMediaSession );
MCEMM_DEBUG("CMceSdpSession::ForkL, Exit ")
return forkedSession;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::IsMaster
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::IsMaster()
{
return iIsMaster;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ContextSwitch
// -----------------------------------------------------------------------------
//
void CMceSdpSession::ContextSwitch( CMceSdpSession* aForkedSession )
{
MCEMM_DEBUG("CMceSdpSession::ContextSwitch, Entry ")
CMceSdpSession* oldMaster = this;
CMceSdpSession* newMaster = aForkedSession;
if ( !newMaster && !oldMaster->IsMaster() )
{
newMaster = this;
oldMaster = NULL;
CMceSdpSession::TIterator
masterCandidates( Manager().iMceSdpSessions,
CMceSdpSession::TIterator::EFilterMaster );
MCE_ITERATOR_FIND_NEXT( masterCandidates, oldMaster,
oldMaster->MediaSession()->iMccID ==
newMaster->MediaSession()->iMccID );
}
if ( oldMaster && newMaster )
{
newMaster->iIsMaster = ETrue;
oldMaster->iIsMaster = EFalse;
delete newMaster->iInitialSession;
newMaster->iInitialSession = oldMaster->iInitialSession;
oldMaster->iInitialSession = NULL;
newMaster->iContext = oldMaster->iRequestedContext ?
oldMaster->iRequestedContext :
newMaster->iContext;
newMaster->iRequestedContext = NULL;
oldMaster->iRequestedContext = NULL;
if( aForkedSession )
{
newMaster->MediaSession()->Merge( *oldMaster->MediaSession(),
KMceDeepMergeYes );
}
MCEMM_DEBUG("context switch performed")
}
else
{
MCEMM_DEBUG("no context switch performed!!")
}
MCEMM_DEBUG("CMceSdpSession::ContextSwitch, Exit ")
}
// -----------------------------------------------------------------------------
// CMceSdpSession::ContextSwitchRequested
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::ContextSwitchRequested()
{
return iContext && iRequestedContext && iRequestedContext != iContext;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Context
// -----------------------------------------------------------------------------
//
CSIPDialogAssocBase* CMceSdpSession::Context()
{
return iContext;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::AttachContext
// -----------------------------------------------------------------------------
//
void CMceSdpSession::AttachContext( CSIPDialogAssocBase* aContext )
{
if ( !iContext || !aContext )
{
iContext = aContext;
}
else if ( aContext != iContext )
{
iRequestedContext = aContext;
}
else
{
iRequestedContext = NULL;
}
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::TIterator
// -----------------------------------------------------------------------------
//
CMceSdpSession::TIterator::TIterator(
RPointerArray<CMceSdpSession>& aCodecs,
CMceSdpSession::TIterator::TFilter aFilter )
: iFilter( aFilter ),
iSessions( aCodecs ),
iCurrentIndex( 0 )
{
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::IsEof
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::TIterator::IsEof()
{
return iSessions.Count() == 0 || iCurrentIndex >= iSessions.Count();
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::Next
// -----------------------------------------------------------------------------
//
TBool CMceSdpSession::TIterator::Next( CMceSdpSession*& aCandidate )
{
CMceSdpSession* next = NULL;
while( !next && !IsEof() )
{
CMceSdpSession* session = iSessions[ iCurrentIndex ];
TBool condition = EFalse;
switch( iFilter )
{
case EFilterMaster:
{
condition = session->IsMaster();
break;
}
default:
{
condition = ETrue;
break;
}
}
next = condition ? session : NULL;
iCurrentIndex++;
}
aCandidate = next;
return aCandidate ? ETrue : EFalse;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Current
// -----------------------------------------------------------------------------
//
TInt CMceSdpSession::TIterator::Current()
{
TInt current = KErrNotFound;
if ( iSessions.Count() > 0 )
{
current = iCurrentIndex-1;
current = current < 0 ? 0 : current;
}
return current;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::Remove
// -----------------------------------------------------------------------------
//
TInt CMceSdpSession::TIterator::Remove()
{
TInt current = Current();
if ( current != KErrNotFound )
{
iSessions.Remove( current );
iCurrentIndex = current;
}
return current;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::Reset
// -----------------------------------------------------------------------------
//
void CMceSdpSession::TIterator::Reset()
{
iCurrentIndex = 0;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::SetFilter
// -----------------------------------------------------------------------------
//
void CMceSdpSession::TIterator::SetFilter(
CMceSdpSession::TIterator::TFilter aFilter )
{
iFilter = aFilter;
}
// -----------------------------------------------------------------------------
// CMceSdpSession::TIterator::Count
// -----------------------------------------------------------------------------
//
TInt CMceSdpSession::TIterator::Count()
{
TInt count = iSessions.Count();
if ( iFilter )
{
TInt currentIndex = iCurrentIndex;
Reset();
CMceSdpSession* codec = NULL;
count = 0;
while( Next( codec ) )
{
count++;
}
iCurrentIndex = currentIndex;
}
return count;
}
void CMceSdpSession::UpdateSecureStreamL( CMceComSession& aSession )
{
MCEMM_DEBUG("CMceSdpSession::UpdateSecureStream() : Entry ")
RPointerArray< CSdpMediaField >& mediaLines = iSdpRemoteMediaFields;
RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
CSdpMediaField* mediaLine = NULL;
CMceComMediaStream* aStream = NULL;
for ( TInt index = 0; index < mediaLines.Count(); index++ )
{
mediaLine = mediaLines[ index ];
aStream = MediaSlotInUse( index, streams );
if( aSession.SecureSession() && aStream )
{
aStream = aStream->OfferStream();
aSession.SecureSession()->ForceUpdateSecureStreamL(*aStream, *mediaLine );
}
}
MCEMM_DEBUG("CMceSdpSession::UpdateSecureStream() : Exit ")
}