multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesdpsession.cpp
changeset 0 1bce908db942
child 3 513a8b745b2f
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include <e32base.h>
       
    24 #include <e32std.h>
       
    25 
       
    26 #include <sdporiginfield.h>
       
    27 #include <sdpconnectionfield.h>
       
    28 #include <sdpfmtattributefield.h>
       
    29 #include <sdpmediafield.h>
       
    30 #include <sdpattributefield.h>
       
    31 #include <sdpcodecstringpool.h>
       
    32 #include <sdpdocument.h>
       
    33 #include <sdpbandwidthfield.h>
       
    34 #include <siptoheader.h>
       
    35 
       
    36 #include "mcemediadefs.h"
       
    37 #include "mcesdpsession.h"
       
    38 #include "mcecomsession.h"
       
    39 #include "mcecommediastream.h"
       
    40 #include "mcemediastream.h"
       
    41 #include "mcesdpcodec.h"
       
    42 #include "mcemediamanager.h"
       
    43 #include "mcemediadefs.h"
       
    44 #include "mcesrvlogs.h"
       
    45 #include "mcemmlogs.h"
       
    46 #include "mcepreconditions.h"
       
    47 #include "mcemediaobserver.h"
       
    48 #include "mcemediastate.h"
       
    49 
       
    50 
       
    51 _LIT8(KTBCP, "TBCP"); 
       
    52 
       
    53 // ================= MEMBER FUNCTIONS ==========================================
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CMceSdpSession::NewL
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 CMceSdpSession* CMceSdpSession::NewL( 
       
    60     CMceComSession& aSession,
       
    61     CMceMediaManager& aManager )
       
    62     {
       
    63     CMceSdpSession* self = NewLC( aSession, aManager );
       
    64     CleanupStack::Pop( self ); 
       
    65     return self;
       
    66     }
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CMceSdpSession::NewLC
       
    70 // -----------------------------------------------------------------------------
       
    71  CMceSdpSession* CMceSdpSession::NewLC( 
       
    72     CMceComSession& aSession,
       
    73     CMceMediaManager& aManager )
       
    74     {
       
    75     CMceSdpSession* self = new ( ELeave ) CMceSdpSession( aSession, aManager );
       
    76     CleanupStack::PushL( self );
       
    77     self->ConstructL();
       
    78     return self;
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CMceSdpSession::CMceSdpSession
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 CMceSdpSession::CMceSdpSession( 
       
    86     CMceComSession& aSession,
       
    87     CMceMediaManager& aManager )
       
    88     :       iManager( aManager ),
       
    89             iSessionId( 0 ),
       
    90             iSessionVersion( 0 ),
       
    91             iSession( &aSession ),
       
    92             iStringTable( NULL ),
       
    93             iOOldSchool( 0 ),
       
    94             iIOldSchool( 0 ),
       
    95             iOOldSchoolProceeding( 0 ),
       
    96             iOOldSchoolCompleted( 0 ),
       
    97             iIsMaster( ETrue ),
       
    98             iOldLocalMediaPort( 0 )
       
    99     {
       
   100     iSessionId = GetRandomNumber();
       
   101     iSessionVersion = GetRandomNumber();
       
   102     iIsSignallingRequired = KMceNoSignalling;
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CMceSdpSession::ConstructL
       
   107 // -----------------------------------------------------------------------------
       
   108 void CMceSdpSession::ConstructL()
       
   109     {
       
   110     SetUserNameL(KMceSdpDefaultUserName);
       
   111     SetSessionNameL(KMceSdpDefaultSessionName);
       
   112 
       
   113     iStringPool = SdpCodecStringPool::StringPoolL();
       
   114     iStringTable = &SdpCodecStringPool::StringTableL(); 
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CMceSdpSession::~CMceSdpSession
       
   119 // -----------------------------------------------------------------------------
       
   120 //   
       
   121 CMceSdpSession::~CMceSdpSession()
       
   122     {
       
   123     delete iInitialSession;
       
   124     delete iSessionName;
       
   125     delete iUserName;
       
   126     delete iRemoteOrigin;
       
   127     iSdpRemoteMediaFields.ResetAndDestroy();
       
   128     if ( MediaSession() )
       
   129         {
       
   130         MediaSession()->DetachSDPSession();
       
   131         }
       
   132     if ( Backup() )
       
   133         {
       
   134         Backup()->DetachSDPSession();
       
   135         }
       
   136     }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // CMceSdpSession::Manager
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 CMceMediaManager& CMceSdpSession::Manager() const
       
   143     {
       
   144     return iManager;
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CMceSdpSession::SignallingRequired
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 TInt& CMceSdpSession::SignallingRequired()
       
   152     {
       
   153     return iIsSignallingRequired;
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CMceSdpSession::CreateOfferL
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 CSdpDocument* CMceSdpSession::CreateOfferL( 
       
   161     CMceComSession& aSession,
       
   162     CMceSdpSession::TOfferType aType )
       
   163     {
       
   164     MCEMM_DEBUG("CMceSdpSession::CreateOfferL(), Entry ")
       
   165     
       
   166     CSdpDocument* sdpDocument = NULL;
       
   167 
       
   168     if ( aType == CMceSdpSession::ERefresh )
       
   169         {
       
   170         User::LeaveIfNull( iSdpDocument );
       
   171         EncodeSessionParamsL( aSession, *iSdpDocument, aType );
       
   172         if(iOldLocalMediaPort != iSdpDocument->MediaFields()[0]->Port())
       
   173             {
       
   174             iSdpDocument->MediaFields()[0]->SetPortL( iOldLocalMediaPort );
       
   175             }
       
   176         return iSdpDocument;
       
   177         }
       
   178         
       
   179     if ( aType == CMceSdpSession::EFirst )
       
   180         {
       
   181         sdpDocument = CSdpDocument::NewLC();
       
   182         }
       
   183     else
       
   184         {
       
   185         sdpDocument = iSdpDocument;
       
   186         CleanSessionParams( *iSdpDocument );
       
   187         }
       
   188 
       
   189     EncodeSessionParamsL( aSession, *sdpDocument, aType );
       
   190     
       
   191     EncodeClientAttributesL( aSession, *sdpDocument );
       
   192     
       
   193     //create offer based on receive, receive only or send stream
       
   194     RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
       
   195     RPointerArray< CSdpMediaField >& mediaLines = sdpDocument->MediaFields();
       
   196     CSdpMediaField* mediaLine = NULL;
       
   197     CMceSdpCodec* sdpCodec = NULL;
       
   198     CMceComMediaStream* mediastream = NULL;
       
   199 
       
   200     if ( aSession.iPullModeUpdate && aType == CMceSdpSession::EUpdate ) 
       
   201 	    {
       
   202 	    // matching the streams to media lines in Pull mode update case
       
   203 	    MatchingStreamsToMLinesL( *sdpDocument, aSession );
       
   204 	    }
       
   205     
       
   206     for ( TInt index = 0; index < streams.Count(); index++ )
       
   207         {
       
   208         mediastream = streams[ index ];
       
   209         TBool add = MediaLineLC( mediaLine, sdpCodec, mediastream,
       
   210                                  mediaLines, streams );
       
   211         if ( mediaLine )
       
   212         	{
       
   213         	
       
   214             if (!add)
       
   215                 {
       
   216                 mediaLine->SetPortL( mediastream->iLocalMediaPort );
       
   217                 }
       
   218             mediastream = mediastream->OfferStream();//downlink
       
   219             sdpCodec->PrepareForEncodeL( *mediastream, *mediaLine );
       
   220             sdpCodec->EncodeMediaOfferL( *mediastream, *mediaLine, *sdpDocument );
       
   221             if ( add )
       
   222                 {
       
   223                 mediaLines.AppendL( mediaLine );
       
   224                 CleanupStack::Pop( mediaLine );
       
   225                 mediastream->SdpIndex() = mediaLines.Count() - 1;
       
   226                 }
       
   227                 
       
   228             }
       
   229         }   
       
   230 
       
   231     User::LeaveIfError( sdpDocument->IsValid() );
       
   232     
       
   233     if ( aType == CMceSdpSession::EFirst )
       
   234         {
       
   235         CleanupStack::Pop( sdpDocument );
       
   236         }
       
   237 
       
   238     iOldLocalMediaPort = sdpDocument->MediaFields()[0]->Port();
       
   239         
       
   240     MCEMM_DEBUG("CMceSdpSession::CreateOfferL(), Exit ")
       
   241     
       
   242     return sdpDocument;
       
   243     }
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CMceSdpSession::MatchingStreamsAndMLinesL
       
   247 // -----------------------------------------------------------------------------
       
   248 //
       
   249 void CMceSdpSession::MatchingStreamsToMLinesL( 
       
   250     CSdpDocument& aSdpDocument, 
       
   251     CMceComSession& aSession )
       
   252     {
       
   253     MCEMM_DEBUG("CMceSdpSession::MatchingStreamsToMLinesL(),entry ")
       
   254 
       
   255     //create offer based on receive, receive only or send stream
       
   256     RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
       
   257     RPointerArray< CSdpMediaField >& mediaLines = aSdpDocument.MediaFields();
       
   258   
       
   259     // set SDPindex for stream if related meida line is found
       
   260     for ( TInt index = 0; index < streams.Count(); index++ )
       
   261         {
       
   262         CMceComMediaStream* mediastream = streams[ index ];
       
   263         CMceSdpCodec* sdpCodecStream = NULL;
       
   264       
       
   265         sdpCodecStream = Manager().SdpCodec( *mediastream );
       
   266         if ( sdpCodecStream )
       
   267           	{
       
   268           	TInt mediaIndex = 0;
       
   269             while( mediaIndex < mediaLines.Count() )
       
   270               	{
       
   271                 CSdpMediaField* mediaLine = mediaLines[ mediaIndex ];
       
   272                 CMceSdpCodec* sdpCodecMediaLine = NULL;
       
   273                 sdpCodecMediaLine = Manager().SdpCodec( *mediaLine  );
       
   274                 if ( sdpCodecMediaLine && sdpCodecMediaLine->Media() == sdpCodecStream->Media() )
       
   275                     {
       
   276                     mediastream->SdpIndex() = mediaIndex;
       
   277                     }  
       
   278                 mediaIndex++;          
       
   279                 }
       
   280           	}
       
   281         MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), stream index:", index )
       
   282         MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), stream SdpIndex:", 
       
   283             mediastream->SdpIndex() )
       
   284         }
       
   285       
       
   286     // set port to 0 if there are unused media lines
       
   287     for ( TInt index = 0; index < mediaLines.Count(); index++ )
       
   288         {
       
   289         // set old session media lines port to 0
       
   290         CSdpMediaField* mediaLine = mediaLines[ index ];
       
   291         
       
   292         TBool indexFoundFromStream = EFalse;
       
   293         TInt streamIndex = 0;
       
   294         while( !indexFoundFromStream && streamIndex < streams.Count() )
       
   295         	{
       
   296         	CMceComMediaStream* mediastream = streams[ streamIndex ];
       
   297         	if ( index == mediastream->SdpIndex() ) 
       
   298         		{
       
   299         		indexFoundFromStream = ETrue;
       
   300         		}
       
   301         	streamIndex++;
       
   302         	}
       
   303         if ( !indexFoundFromStream )
       
   304         	{
       
   305             MCEMM_DEBUG_DVALUE( "CMceSdpSession::MatchingStreamsToMLinesL(), \
       
   306     set media line to 0, index:", index )
       
   307         	mediaLine->SetPortL( 0 );  
       
   308         	}
       
   309         }
       
   310         
       
   311     MCEMM_DEBUG("CMceSdpSession::MatchingStreamsToMLinesL(),exit ")
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CMceSdpSession::DecodeAnswerL
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 TInt CMceSdpSession::DecodeAnswerL( 
       
   319     CSdpDocument& aSdpDocument, 
       
   320     CMceComSession& aSession )                                
       
   321     {
       
   322     MCEMM_DEBUG("CMceSdpSession::DecodeAnswerL(), Entry ")
       
   323     
       
   324     iSdpDocument = &aSdpDocument;
       
   325     RPointerArray< CSdpMediaField >& mediaLines = iSdpDocument->MediaFields();
       
   326     if ( mediaLines.Count() == 0 )
       
   327         {
       
   328         User::Leave( KErrArgument );
       
   329         }
       
   330     
       
   331     // store the remote o= field
       
   332     StoreRemoteOriginL();
       
   333     // store the remote a= field
       
   334     StoreRemoteMediaFieldsL();
       
   335 
       
   336     TInt err = SetRemoteIpAddressL( aSession, aSdpDocument );
       
   337     if ( err != KErrNone )
       
   338         {
       
   339         MCEMM_DEBUG("ERROR: Incompatible network address")
       
   340         User::Leave( KErrArgument );
       
   341         }
       
   342 
       
   343     // handle media lines
       
   344     RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
       
   345     
       
   346     CSdpMediaField* mediaLine = NULL;
       
   347     CMceSdpCodec* sdpCodec = NULL;
       
   348     CMceComMediaStream* mediastream = NULL;
       
   349     TInt index = 0;
       
   350 
       
   351 	// Go through the answer's media lines. If there is a line for which there
       
   352 	// is no stream (remote has put wrong port to answer), set port to zero.
       
   353 	// Do this before the second for-loop, as DecodeMediaAnswerL may leave with
       
   354 	// KMceErrOldSchool, starting old school hold. In that case any further
       
   355 	// media lines would not be processed and if they had wrong port (non-zero
       
   356 	// port but no media stream), we'd use that in our next offer.
       
   357 	if ( !aSession.iPullModeUpdate )
       
   358 		{
       
   359 		for ( index = 0; index < mediaLines.Count(); index++ )
       
   360         	{
       
   361         	mediaLine = mediaLines[ index ];
       
   362 			if ( Manager().SdpCodec( *mediaLine ) &&
       
   363 				 !MediaSlotInUse( index, streams ) )
       
   364 				{
       
   365 				mediaLine->SetPortL( 0 );
       
   366 				}
       
   367             }
       
   368         }
       
   369 
       
   370     for ( index = 0; index < mediaLines.Count(); index++ )
       
   371         {
       
   372         mediaLine = mediaLines[ index ];
       
   373         sdpCodec = Manager().SdpCodec( *mediaLine );
       
   374 
       
   375         if ( sdpCodec )
       
   376             {
       
   377             if ( !aSession.iPullModeUpdate )
       
   378                 {
       
   379                 TUint remotePort = mediaLine->Port();            
       
   380                 aSession.iRemoteIpAddress.SetPort( remotePort );
       
   381 
       
   382                 mediastream = MediaSlotInUse( index, streams );
       
   383                 // Check for local Support of media and only decode media
       
   384         		// which we support or in use
       
   385 				if ( mediastream )
       
   386 					{
       
   387 	                mediastream = mediastream->AnswerStream();//uplink
       
   388 	                __ASSERT_ALWAYS( mediastream , User::Leave( KErrArgument ) );
       
   389 	                
       
   390 	                mediastream->SetRemoteMediaPort( remotePort );
       
   391 	                
       
   392 	                if ( remotePort )
       
   393 	                    {
       
   394 	                    TInt warnings = KErrNone;
       
   395 	                    sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
       
   396 	                    warnings = sdpCodec->DecodeMediaAnswerL( *mediaLine,
       
   397 	                    										 *mediastream,
       
   398 	                    										 aSdpDocument );
       
   399 	                    if ( warnings  >= KMceSipBadRequest)
       
   400 	                    	{
       
   401 	                    	return warnings;
       
   402 	                    	}
       
   403 	                    mediastream->DecodedL( KMceRoleOfferer );
       
   404 	                    }
       
   405 	                else //rejected
       
   406 	                    {
       
   407 	                    mediastream->SetDirection( SdpCodecStringConstants::EAttributeInactive );
       
   408 	                    mediastream->SdpIndex() = KErrNotFound;
       
   409 	                    }
       
   410 					}
       
   411                 }
       
   412             else
       
   413                 {
       
   414                 DecodePullModeUpdateMediaLineL(
       
   415                     aSdpDocument, aSession, *mediaLine, index, *sdpCodec );
       
   416                 }
       
   417             }
       
   418         else
       
   419             {
       
   420             MCEMM_DEBUG_SVALUE("No SDP codec. m-line", mediaLine->Media().DesC() )
       
   421             }
       
   422         }
       
   423 
       
   424     //check that all answers to offers were received        
       
   425     User::LeaveIfError( MediaSlotInUse( index, streams ) ? KErrArgument : KErrNone );
       
   426     
       
   427     // set the o= field with the local information
       
   428     EncodeSessionParamsL( aSession, *iSdpDocument );
       
   429     
       
   430     // store session level attributes
       
   431     DecodeClientAttributesL( aSdpDocument, aSession );
       
   432     
       
   433     MCEMM_DEBUG("CMceSdpSession::DecodeAnswerL(), Exit ")
       
   434     
       
   435     return KErrNone;
       
   436     }
       
   437 
       
   438 // -----------------------------------------------------------------------------
       
   439 // CMceSdpSession::DecodePullModeUpdateMediaLineL
       
   440 // -----------------------------------------------------------------------------
       
   441 //
       
   442 void CMceSdpSession::DecodePullModeUpdateMediaLineL( 
       
   443     CSdpDocument& aSdpDocument, 
       
   444     CMceComSession& aSession,
       
   445     CSdpMediaField& aMediaLine,
       
   446     TInt aIndex,
       
   447     CMceSdpCodec& aSdpCodec ) 
       
   448     {
       
   449     MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), Entry ")
       
   450 
       
   451     RPointerArray <CMceComMediaStream>& streams = aSession.Streams();
       
   452     CMceComMediaStream* mediastream = NULL;
       
   453    
       
   454     TUint remotePort = aMediaLine.Port();
       
   455        
       
   456     aSession.iRemoteIpAddress.SetPort( remotePort );
       
   457 
       
   458     // this media line might be from previous session, and it's
       
   459     // port is 0, if so mediastream can't be found
       
   460     mediastream = MediaSlotInUse( aIndex, streams );
       
   461     
       
   462     MCEMM_DEBUG_DVALUE( "CMceSdpSession::DecodePullModeUpdateMediaLineL, remotePort:", 
       
   463                          remotePort )
       
   464     if ( mediastream )
       
   465         {
       
   466         MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), stream found ")
       
   467 
       
   468         mediastream = mediastream->AnswerStream();//uplink
       
   469         __ASSERT_ALWAYS( mediastream , User::Leave( KErrArgument ) );
       
   470         mediastream->SetRemoteMediaPort( remotePort ); 
       
   471         if ( remotePort )
       
   472             {
       
   473             aSdpCodec.PrepareForDecodeL( aMediaLine, mediastream );
       
   474             aSdpCodec.DecodeMediaAnswerL( aMediaLine, *mediastream, aSdpDocument );
       
   475             mediastream->DecodedL( KMceRoleOfferer );
       
   476             }
       
   477         else
       
   478             {
       
   479             mediastream->SetDirection( SdpCodecStringConstants::EAttributeInactive );
       
   480             mediastream->SdpIndex() = KErrNotFound;
       
   481             }
       
   482         }
       
   483     
       
   484     // if streams not found and port in meida line is not 0
       
   485     // leave with KErrNotFound       
       
   486     User::LeaveIfError( (!mediastream && remotePort) ? KErrNotFound : KErrNone );
       
   487     
       
   488     MCEMM_DEBUG("CMceSdpSession::DecodePullModeUpdateMediaLineL(), Exit ")
       
   489     }
       
   490                                              
       
   491 // -----------------------------------------------------------------------------
       
   492 // CMceSdpSession::DecodeOfferL
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 TInt CMceSdpSession::DecodeOfferL( 
       
   496     CSdpDocument& aSdpDocument, 
       
   497     CMceComSession& aSession )
       
   498     {
       
   499     MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Entry ")
       
   500     TInt result = KErrNone;
       
   501     
       
   502     iSdpDocument = &aSdpDocument;
       
   503     
       
   504     RPointerArray <CSdpMediaField>& mediaLines = iSdpDocument->MediaFields();
       
   505     if ( mediaLines.Count() == 0 )
       
   506         {
       
   507         MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), ERROR: No media lines")
       
   508         MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Exit ")
       
   509         return KMceSipWarnIncompatibleMediaFormat;
       
   510         }
       
   511         
       
   512     // store the remote o= field
       
   513     StoreRemoteOriginL();
       
   514     // store the remote a= field
       
   515     StoreRemoteMediaFieldsL();
       
   516     //set remote ip address
       
   517     result = SetRemoteIpAddressL( aSession, aSdpDocument );
       
   518     
       
   519     if ( result != KErrNone )
       
   520         {
       
   521         MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), ERROR: Incompatible network address")
       
   522         MCEMM_DEBUG("CMceSdpSession::DecodeOfferL(), Exit ")
       
   523         return result;
       
   524         }
       
   525 
       
   526     DecodeConnectionFieldL( *iSdpDocument, aSession );
       
   527     
       
   528     // handle media lines
       
   529     RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
       
   530     CSdpMediaField* mediaLine = NULL;
       
   531     CMceSdpCodec* sdpCodec = NULL;
       
   532     CMceComMediaStream* mediastream = NULL;
       
   533     
       
   534     TInt streamCount( 0 );
       
   535     for ( TInt i = 0; i < streams.Count(); i++ )
       
   536         {
       
   537         if ( streams[ i ]->iStreamType != CMceComMediaStream::ELocalStream )
       
   538             {
       
   539             streamCount++;
       
   540             }
       
   541         }
       
   542    
       
   543    	if ( streamCount > mediaLines.Count() )
       
   544    		{
       
   545    		return KMceSipNotAcceptableHere;
       
   546    		}
       
   547    
       
   548     TInt index = 0;
       
   549    
       
   550     while( index < mediaLines.Count() )
       
   551         {
       
   552         mediaLine = mediaLines[ index ];
       
   553         TUint remotePort = mediaLine->Port();
       
   554         if ( remotePort )
       
   555             {
       
   556             sdpCodec = Manager().SdpCodec( *mediaLine );
       
   557             if ( sdpCodec )
       
   558                 {
       
   559                 TInt warning = KErrNone;
       
   560                 
       
   561                 aSession.iRemoteIpAddress.SetPort( remotePort );
       
   562                 
       
   563                 mediastream = MediaSlotInUse( index, streams );
       
   564                 if ( !mediastream )
       
   565                     {
       
   566                     sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
       
   567                     warning = sdpCodec->DecodeMediaOfferL( *mediaLine, mediastream, 
       
   568                                                             aSession, aSdpDocument );
       
   569                     }
       
   570                 else
       
   571                     {
       
   572                     //update
       
   573                     mediastream = mediastream->AnswerStream();//uplink
       
   574                     sdpCodec->PrepareForDecodeL( *mediaLine, mediastream );
       
   575                     warning = sdpCodec->DecodeMediaUpdateL( *mediaLine, *mediastream, 
       
   576                                                             aSdpDocument );
       
   577                     }
       
   578                 if ( warning >= KMceSipBadRequest )
       
   579                     {
       
   580                     return warning;
       
   581                     }
       
   582                     
       
   583                 if ( warning != KErrNone )
       
   584                     {
       
   585                     //media will be rejected when answer is created
       
   586                     if ( mediastream )
       
   587                         {
       
   588                         TInt streamIndex = aSession.Streams().Find( &(*mediastream)() );
       
   589                         __ASSERT_ALWAYS( streamIndex >= 0, User::Leave( KErrArgument ) );
       
   590                         MCEMM_DEBUG_DVALUE("removing stream", streamIndex )
       
   591                         aSession.Streams().Remove( streamIndex );
       
   592                         delete mediastream;
       
   593                         }
       
   594                     }
       
   595                 else
       
   596                     {
       
   597                     __ASSERT_ALWAYS( mediastream, User::Leave( KErrArgument ) );
       
   598                     mediastream->DecodedL( KMceRoleAnswerer );
       
   599                     mediastream->SdpIndex() = index;
       
   600                     }
       
   601                 }
       
   602             else
       
   603                 {
       
   604                 MCEMM_DEBUG_SVALUE("No SDP codec. m-line", mediaLine->Media().DesC() )
       
   605                 }
       
   606             }
       
   607         index++;
       
   608         }
       
   609 
       
   610     
       
   611     if( streams.Count() > 0 )
       
   612         {
       
   613         // at least one media line successfully decoded and corresponding 
       
   614         // server streams created or inactive media line received
       
   615         MCEMM_DEBUG("Incoming OFFER successfully decoded")
       
   616         }
       
   617     else 
       
   618         {
       
   619         MCEMM_DEBUG("ERROR: Negotiation failed")
       
   620         result = KMceSipWarnMediaTypeNotAvailable;
       
   621         }
       
   622     
       
   623     if ( result == KErrNone )
       
   624         {
       
   625         // store session level attributes
       
   626         DecodeClientAttributesL( aSdpDocument, aSession );
       
   627         }
       
   628         
       
   629     MCEMM_DEBUG_DVALUE("CMceSdpSession::DecodeOfferL(), Exit ", result )
       
   630     return result;
       
   631     }      
       
   632     
       
   633 // -----------------------------------------------------------------------------
       
   634 // CMceSdpSession::CreateAnswerL
       
   635 // -----------------------------------------------------------------------------
       
   636 //
       
   637 CSdpDocument& CMceSdpSession::CreateAnswerL( 
       
   638     CMceComSession& aSession, 
       
   639     TBool aInvalid )
       
   640     {       
       
   641     MCEMM_DEBUG("CMceSdpSession::CreateAnswerL(), Entry ")
       
   642     
       
   643     TOfferType type = !Backup() ? EFirst : EUpdate;
       
   644     
       
   645     CleanSessionParams( *iSdpDocument );
       
   646 
       
   647     EncodeSessionParamsL( aSession, *iSdpDocument, type );
       
   648     
       
   649     EncodeClientAttributesL( aSession, *iSdpDocument );
       
   650     
       
   651     RPointerArray <CSdpMediaField>& mediaLines = iSdpDocument->MediaFields();
       
   652     
       
   653     __ASSERT_ALWAYS( mediaLines.Count() > 0, User::Leave( KErrArgument ) );
       
   654 
       
   655     RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
       
   656     CSdpMediaField* mediaLine = NULL;
       
   657     CMceSdpCodec* sdpCodec = NULL;
       
   658     CMceComMediaStream* mediastream = NULL;
       
   659     TInt index = 0;
       
   660 
       
   661     if ( !aInvalid )
       
   662         {
       
   663         
       
   664         for ( index = 0; index < streams.Count(); index++ )
       
   665             {
       
   666             mediastream = streams[ index ];
       
   667             TBool add = MediaLineLC( mediaLine, sdpCodec, mediastream,
       
   668                                      mediaLines, streams );
       
   669 
       
   670             User::LeaveIfError( add ? KErrNotFound : KErrNone );
       
   671                                      
       
   672             if ( mediaLine )
       
   673                 {
       
   674                 mediastream = mediastream->OfferStream();//downlink
       
   675                 sdpCodec->PrepareForEncodeL( *mediastream, *mediaLine );
       
   676                 PrepareForAnswerEncodeL( *mediaLine );
       
   677                 sdpCodec->EncodeMediaAnswerL( *mediastream, *mediaLine, *iSdpDocument );
       
   678                 }
       
   679             }
       
   680         //reject removed streams
       
   681         //ignore the Supported File Stream will be handled by other plugin
       
   682         
       
   683         for ( index = 0; index < mediaLines.Count(); index++ )
       
   684             {
       
   685             mediaLine = mediaLines[ index ];
       
   686             sdpCodec = Manager().SdpCodec( *mediaLine );
       
   687                         
       
   688             if ( sdpCodec || mediaLine->FormatList() != KTBCP )
       
   689                 {
       
   690                 if ( !MediaSlotInUse( index, streams ) )
       
   691                     {
       
   692                     MCEMM_DEBUG_SVALUE("Rejecting media line", mediaLine->Media().DesC() )
       
   693                     mediaLines[ index ]->RejectMedia();
       
   694                     }
       
   695                 }
       
   696             }
       
   697         MCEMM_DEBUG("Negotiation successful! Answer created ")
       
   698         }
       
   699     else
       
   700         {
       
   701         MCEMM_DEBUG("Negotiation failed! Reject all media lines ")
       
   702         // negotiation failed, reject all media lines in the offer
       
   703         for (index = 0; index < mediaLines.Count(); index++)
       
   704             {
       
   705             mediaLines[ index ]->RejectMedia();
       
   706             }
       
   707         }
       
   708         
       
   709     User::LeaveIfError( iSdpDocument->IsValid() );
       
   710 
       
   711     iOldLocalMediaPort = iSdpDocument->MediaFields()[0]->Port();
       
   712 
       
   713     MCEMM_DEBUG("CMceSdpSession::CreateAnswerL(), Exit ")
       
   714     
       
   715     return *iSdpDocument;
       
   716     }       
       
   717 
       
   718 // -----------------------------------------------------------------------------
       
   719 // CMceSdpSession::PrepareForAnswerEncodeL
       
   720 // -----------------------------------------------------------------------------
       
   721 //
       
   722 void CMceSdpSession::PrepareForAnswerEncodeL( CSdpMediaField& aMediaLine )
       
   723     {   
       
   724     TLex8 formats( aMediaLine.FormatList() );
       
   725     while( !formats.Eos() )
       
   726         {
       
   727         TPtrC8 format = formats.NextToken();
       
   728         aMediaLine.RemoveFormatL( format );
       
   729         }
       
   730     }
       
   731 
       
   732 // -----------------------------------------------------------------------------
       
   733 // CMceSdpSession::CreateMediaLineLC
       
   734 // -----------------------------------------------------------------------------
       
   735 //
       
   736 CSdpMediaField* CMceSdpSession::CreateMediaLineLC( 
       
   737     CMceComMediaStream& aStream ) const
       
   738     {
       
   739     RStringF protocol = SDP_STRING( SdpCodecStringConstants::EProtocolRtpAvp );
       
   740         
       
   741     CSdpMediaField* medialine = 
       
   742             CSdpMediaField::NewLC( Manager().SdpCodec( aStream )->Media(), 
       
   743                                    aStream.iLocalMediaPort,
       
   744                                    protocol, 
       
   745                                    KMceSdpNullFormatList );
       
   746     return medialine;
       
   747     }    
       
   748 
       
   749 // -----------------------------------------------------------------------------
       
   750 // CMceSdpSession::MediaLineLC
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 TBool CMceSdpSession::MediaLineLC( 
       
   754     CSdpMediaField*& aMediaLine,
       
   755     CMceSdpCodec*& sdpCodec,
       
   756     CMceComMediaStream* aStream,
       
   757     RPointerArray<CSdpMediaField>& aMediaLines,
       
   758     RPointerArray<CMceComMediaStream>& aStreams )
       
   759     {
       
   760     
       
   761     //filter out local streams
       
   762     if ( !aStream || 
       
   763          !Manager().SdpCodec( *aStream ) )
       
   764         {
       
   765         aMediaLine = NULL;
       
   766         sdpCodec = NULL;
       
   767         return EFalse;
       
   768         }
       
   769         
       
   770     sdpCodec = Manager().SdpCodec( *aStream );
       
   771     
       
   772     TInt mediaIndex = aStream->SdpIndex();
       
   773     
       
   774     if ( mediaIndex == KErrNotFound )
       
   775         {
       
   776         TInt index = 0;
       
   777         TBool inUse = ETrue;
       
   778         while( inUse && index < aMediaLines.Count() )
       
   779             {
       
   780             CSdpMediaField* mediaLine = aMediaLines[ index ];
       
   781             if ( Manager().SdpCodec( *mediaLine ) )
       
   782                 {
       
   783                 inUse = MCE_NOT_NULL_PTR( MediaSlotInUse( index, aStreams ) );
       
   784                 }
       
   785             mediaIndex = !inUse ? index : mediaIndex;
       
   786             index++;                
       
   787             }
       
   788         }
       
   789 
       
   790                     
       
   791     if ( mediaIndex == KErrNotFound )//all in use
       
   792         {
       
   793         aMediaLine = CreateMediaLineLC( *aStream );
       
   794         }
       
   795     else 
       
   796         {
       
   797         __ASSERT_ALWAYS( aMediaLines.Count() > mediaIndex , User::Leave( KErrArgument ) );
       
   798         aMediaLine = aMediaLines[ mediaIndex ];
       
   799         }
       
   800     
       
   801     __ASSERT_ALWAYS( Manager().SdpCodec( *aMediaLine ), User::Leave( KErrArgument ) );
       
   802                      
       
   803     return mediaIndex == KErrNotFound;  
       
   804     }
       
   805 
       
   806 // -----------------------------------------------------------------------------
       
   807 // CMceSdpSession::MediaSlotInUse
       
   808 // -----------------------------------------------------------------------------
       
   809 //
       
   810 CMceComMediaStream* CMceSdpSession::MediaSlotInUse( 
       
   811     TInt aMediaLine, 
       
   812     RPointerArray<CMceComMediaStream>& aStreams )
       
   813     {
       
   814     CMceComMediaStream* stream = NULL;
       
   815     TInt index = 0;
       
   816     while( !stream && index < aStreams.Count() )
       
   817         {
       
   818         stream = aStreams[ index++ ];
       
   819         stream = Manager().SdpCodec( *stream ) && 
       
   820                  stream->SdpIndex() == aMediaLine ? stream : NULL;
       
   821         }
       
   822     
       
   823     return stream;   
       
   824     }
       
   825 
       
   826 // -----------------------------------------------------------------------------
       
   827 // CMceSdpSession::CleanSessionParams
       
   828 // -----------------------------------------------------------------------------
       
   829 //
       
   830 void CMceSdpSession::CleanSessionParams( CSdpDocument& aDocument ) const
       
   831     {
       
   832     MCEMM_DEBUG("CMceSdpSession::CleanSessionParams()")
       
   833     aDocument.AttributeFields().ResetAndDestroy();
       
   834     aDocument.BandwidthFields().ResetAndDestroy();
       
   835     }
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CMceSdpSession::EncodeSessionParamsL
       
   839 // -----------------------------------------------------------------------------
       
   840 //
       
   841 void CMceSdpSession::EncodeSessionParamsL( 
       
   842     CMceComSession& aSession, 
       
   843     CSdpDocument& aDocument, 
       
   844     TOfferType aType )
       
   845     {
       
   846     MCEMM_DEBUG("CMceSdpSession::EncodeSessionParamsL(), Entry ")
       
   847      // Set session name: s=
       
   848     aDocument.SetSessionNameL( *iSessionName );
       
   849 
       
   850     if( aType == EFirst )
       
   851         {
       
   852         // update the name in o= field only when creating intial offer/answer
       
   853         HBufC8* originator = NULL;
       
   854         if ( aSession.iType == CMceComSession::EOutSession )
       
   855             {
       
   856             originator = aSession.iOriginator;
       
   857             }
       
   858         else
       
   859             {
       
   860             originator = aSession.iRecipient;
       
   861             }
       
   862         
       
   863         if (originator && originator->Length() > 0)
       
   864             {
       
   865             CSIPToHeader* to = CSIPToHeader::DecodeL( *originator);
       
   866             CleanupStack::PushL(to);
       
   867             const TDesC8& username = to->SIPAddress().Uri8().Uri().Extract( EUriUserinfo );
       
   868             if ( username.Length() )
       
   869                 {
       
   870                 SetUserNameL( username );
       
   871                 }  
       
   872             else
       
   873                 {
       
   874                 const TDesC8& uripath = to->SIPAddress().Uri8().Uri().Extract( EUriPath );
       
   875                 const TDesC8& uri = to->SIPAddress().Uri8().Uri().UriDes();
       
   876 
       
   877                 if ( uripath.Length() )
       
   878                     {
       
   879                     SetUserNameL( uripath );
       
   880                     }
       
   881                 else
       
   882                     {
       
   883                     SetUserNameL( uri );
       
   884                     }
       
   885                 }
       
   886 			    
       
   887             CleanupStack::PopAndDestroy(to);
       
   888             }
       
   889         }
       
   890     else if( aType == EUpdate )
       
   891         {
       
   892         iSessionVersion++;
       
   893         }
       
   894         
       
   895     CSdpOriginField* originField = 
       
   896                 CSdpOriginField::NewL( UserName(),
       
   897                                       iSessionId,
       
   898                                       iSessionVersion,
       
   899                                       aSession.iLocalIpAddress );
       
   900                                       
       
   901     aDocument.SetOriginField( originField );
       
   902 
       
   903     EncodeConnectionFieldL( aSession, aDocument );
       
   904     
       
   905     MCEMM_DEBUG("CMceSdpSession::EncodeSessionParamsL(), Exit ")
       
   906     }
       
   907 
       
   908 // -----------------------------------------------------------------------------
       
   909 // CMceSdpSession::SetRemoteIpAddressL
       
   910 // -----------------------------------------------------------------------------
       
   911 //
       
   912 TMceSipWarningCode CMceSdpSession::SetRemoteIpAddressL( 
       
   913     CMceComSession& aSession,
       
   914     CSdpDocument& aSdpDocument )
       
   915     {
       
   916     TMceSipWarningCode result = KErrNone;
       
   917     
       
   918     RPointerArray< CSdpMediaField >& mediaLines = aSdpDocument.MediaFields();
       
   919         
       
   920     // get the remote ip address
       
   921     CSdpConnectionField* connfield = aSdpDocument.ConnectionField();
       
   922     const TInetAddr* inetAddr = NULL;
       
   923     
       
   924     if( connfield )
       
   925         {
       
   926 		inetAddr = connfield->InetAddress();
       
   927 		if( inetAddr )
       
   928 		    {
       
   929 		    const TInetAddr inetAddress = *(connfield->InetAddress() );
       
   930 		    // if present, if not then should be media level
       
   931 		    MCE_SET_REMOTE_IP_ADDR( &aSession, inetAddress );
       
   932 		    }
       
   933         }
       
   934     
       
   935     if ( !inetAddr )
       
   936         {
       
   937         TInt index = 0;
       
   938         TBool found = ETrue;
       
   939         while( found && index < mediaLines.Count() )
       
   940             {
       
   941             RPointerArray<CSdpConnectionField>& connfields = 
       
   942                                                 mediaLines[index]->ConnectionFields();
       
   943             
       
   944             if ( mediaLines[index++]->Port() > 0 )
       
   945                 {
       
   946 	            TInt cfindex = 0;
       
   947 	            TBool cffound = EFalse;
       
   948 	            while( !cffound && cfindex < connfields.Count() )
       
   949 	                {
       
   950 	                inetAddr = connfields[cfindex++]->InetAddress();
       
   951 	                cffound = MCE_NOT_NULL_PTR( inetAddr );
       
   952 	                }
       
   953 	            found = cffound;
       
   954                 }
       
   955             }
       
   956         }
       
   957         
       
   958     if ( inetAddr )
       
   959         {
       
   960         MCE_SET_REMOTE_IP_ADDR( &aSession, *inetAddr );
       
   961         }
       
   962     else
       
   963         {
       
   964         result = KMceSipWarnIncompatibleNetworkAddressFormat;
       
   965         }
       
   966 
       
   967     return result;
       
   968     }
       
   969     
       
   970 // -----------------------------------------------------------------------------
       
   971 // CMceSdpSession::SetSessionNameL
       
   972 // -----------------------------------------------------------------------------
       
   973 //
       
   974 void CMceSdpSession::SetSessionNameL( const TDesC8& aSessionName )
       
   975     {
       
   976     HBufC8* tmp = aSessionName.AllocL();
       
   977     delete iSessionName;
       
   978     iSessionName = tmp;
       
   979     }
       
   980 
       
   981 // -----------------------------------------------------------------------------
       
   982 // CMceSdpSession::SetMediaSession
       
   983 // -----------------------------------------------------------------------------
       
   984 //
       
   985 void CMceSdpSession::SetMediaSession( CMceComSession* aSession )
       
   986     {
       
   987     iSession = aSession;
       
   988     }  
       
   989 
       
   990 // -----------------------------------------------------------------------------
       
   991 // CMceSdpSession::MediaSession
       
   992 // -----------------------------------------------------------------------------
       
   993 //
       
   994 CMceComSession* CMceSdpSession::MediaSession()
       
   995     {
       
   996     return iSession;
       
   997     }  
       
   998 
       
   999 // -----------------------------------------------------------------------------
       
  1000 // CMceSdpSession::SetBackup
       
  1001 // -----------------------------------------------------------------------------
       
  1002 //
       
  1003 void CMceSdpSession::SetBackup( CMceComSession* aSession )
       
  1004     {
       
  1005     iBackup = aSession;
       
  1006     }  
       
  1007     
       
  1008 // -----------------------------------------------------------------------------
       
  1009 // CMceSdpSession::Backup
       
  1010 // -----------------------------------------------------------------------------
       
  1011 //
       
  1012 CMceComSession* CMceSdpSession::Backup()
       
  1013     {
       
  1014     return iBackup;
       
  1015     }  
       
  1016 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CMceSdpSession::DetachMedia
       
  1019 // ----------------------------------------------------------------------------- 
       
  1020 //
       
  1021 TBool CMceSdpSession::DetachMedia( CMceComSession& aSession )
       
  1022     {
       
  1023     if ( &aSession == MediaSession() )
       
  1024         {
       
  1025         SetMediaSession( NULL );
       
  1026         }
       
  1027     else if ( &aSession == Backup() )
       
  1028         {
       
  1029         SetBackup( NULL );
       
  1030         }
       
  1031     else
       
  1032         {
       
  1033         return EFalse;
       
  1034         }
       
  1035     return ETrue;
       
  1036     }
       
  1037     
       
  1038 // -----------------------------------------------------------------------------
       
  1039 // CMceSdpSession::SetUserNameL
       
  1040 // -----------------------------------------------------------------------------
       
  1041 //
       
  1042 void CMceSdpSession::SetUserNameL( const TDesC8& aUserName )
       
  1043     {
       
  1044     HBufC8* tmp = aUserName.AllocL();
       
  1045     delete iUserName; 
       
  1046     iUserName = tmp;
       
  1047     }
       
  1048     
       
  1049 // -----------------------------------------------------------------------------
       
  1050 // CMceSdpSession::UserName
       
  1051 // -----------------------------------------------------------------------------
       
  1052 //
       
  1053 const TDesC8& CMceSdpSession::UserName() const
       
  1054     {
       
  1055     return *iUserName;
       
  1056     }
       
  1057 
       
  1058 // ------------------------------------------------------------------------------
       
  1059 // CMceSdpSession::StoreRemoteOriginL
       
  1060 // ------------------------------------------------------------------------------
       
  1061 //
       
  1062 void CMceSdpSession::StoreRemoteOriginL()
       
  1063     {
       
  1064     CSdpOriginField* origin = iSdpDocument->OriginField();
       
  1065     User::LeaveIfNull( origin );
       
  1066     CSdpOriginField* tmp = origin->CloneL();
       
  1067     delete iRemoteOrigin;
       
  1068     iRemoteOrigin = tmp;    	
       
  1069     }      
       
  1070 
       
  1071 // ------------------------------------------------------------------------------
       
  1072 // CMceSdpSession::StoreRemoteMediaFieldsL
       
  1073 // ------------------------------------------------------------------------------
       
  1074 //
       
  1075 void CMceSdpSession::StoreRemoteMediaFieldsL()
       
  1076     {
       
  1077     iSdpRemoteMediaFields.ResetAndDestroy();
       
  1078     for ( TInt i = 0; i < iSdpDocument->MediaFields().Count(); i++ )
       
  1079     	{
       
  1080     	CSdpMediaField* field = iSdpDocument->MediaFields()[i]->CloneL();
       
  1081     	CleanupStack::PushL( field );
       
  1082     	iSdpRemoteMediaFields.AppendL( field );
       
  1083     	CleanupStack::Pop( field );
       
  1084     	}
       
  1085     }     
       
  1086 
       
  1087 // -----------------------------------------------------------------------------
       
  1088 // CMceSdpSession::DecodeConnectionFieldL
       
  1089 // ----------------------------------------------------------------------------- 
       
  1090 //
       
  1091 void CMceSdpSession::DecodeConnectionFieldL( 
       
  1092     CSdpDocument& aSdpDocument,
       
  1093     CMceComSession& aSession )
       
  1094     {
       
  1095     CSdpConnectionField* nullAddress = 
       
  1096                     CSdpConnectionField::DecodeL( KMceSipNullAddressA );
       
  1097     CleanupStack::PushL( nullAddress );
       
  1098     
       
  1099     CMceSdpSession& sdpSession = aSession.SdpSession();
       
  1100     CSdpConnectionField* connectionField = aSdpDocument.ConnectionField();
       
  1101     
       
  1102     if ( connectionField && 
       
  1103         ( connectionField->Address() == nullAddress->Address() ) )
       
  1104     	{
       
  1105     	sdpSession.iIOldSchool = 1;
       
  1106     	}
       
  1107 
       
  1108 	else 
       
  1109 		{
       
  1110 		sdpSession.iIOldSchool = 0;		
       
  1111 		}    	
       
  1112 
       
  1113     CleanupStack::PopAndDestroy( nullAddress );
       
  1114     }
       
  1115 
       
  1116 // -----------------------------------------------------------------------------
       
  1117 // CMceSdpSession::EncodeConnectionFieldL
       
  1118 // ----------------------------------------------------------------------------- 
       
  1119 //
       
  1120 void CMceSdpSession::EncodeConnectionFieldL( 
       
  1121     CMceComSession& aSession,
       
  1122     CSdpDocument& aSdpDocument )   
       
  1123     {   
       
  1124     RPointerArray <CSdpMediaField>& mediaLines = aSdpDocument.MediaFields();
       
  1125     TInt mediaLinesIndex = 0;
       
  1126     TBool found = EFalse;
       
  1127     TInt mCLineCount = 0;
       
  1128     while( mediaLinesIndex < mediaLines.Count() )
       
  1129         {
       
  1130         RPointerArray<CSdpConnectionField>& connfields = 
       
  1131             mediaLines[mediaLinesIndex++]->ConnectionFields();
       
  1132        
       
  1133         TInt connfieldsIndex = 0;        
       
  1134         while( connfieldsIndex < connfields.Count() )
       
  1135             {
       
  1136             if ( !connfieldsIndex )
       
  1137                 {
       
  1138                 mCLineCount++;
       
  1139                 }
       
  1140 
       
  1141             CSdpConnectionField* connectionField = connfields[connfieldsIndex++];
       
  1142             
       
  1143             // if there are media level c= lines, copy the local address
       
  1144             // to be media c= lines
       
  1145             if ( iIOldSchool )
       
  1146                 {
       
  1147                 connectionField->SetAddressL( 
       
  1148                     connectionField->NetType(), 
       
  1149                     connectionField->AddressType(),
       
  1150                     KMceSipNullAddress );
       
  1151                 }
       
  1152             else
       
  1153                 {
       
  1154                 connectionField->SetInetAddressL( aSession.iLocalIpAddress ); 
       
  1155                 }
       
  1156             }
       
  1157 
       
  1158         // each media line have a media c= line
       
  1159         if ( mCLineCount == mediaLines.Count() )
       
  1160             {
       
  1161             found = ETrue;
       
  1162             }
       
  1163         }
       
  1164 
       
  1165     if ( !found || aSdpDocument.ConnectionField() )
       
  1166         {
       
  1167         
       
  1168         // rfc4566 5.7 Connection Data ("c="), media level c= lines are more 
       
  1169         // important and will override session level c= line if both exists, copy 
       
  1170         // the local address to be session level c= line when MO provide it also
       
  1171         CSdpConnectionField* connectionField = NULL;
       
  1172         if ( iIOldSchool )
       
  1173             {
       
  1174             connectionField = CSdpConnectionField::DecodeL( KMceSipNullAddressA );
       
  1175             }
       
  1176         else
       
  1177             {
       
  1178             connectionField = CSdpConnectionField::NewL( aSession.iLocalIpAddress );
       
  1179             }
       
  1180             
       
  1181         aSdpDocument.SetConnectionField( connectionField );  
       
  1182         }
       
  1183     }
       
  1184         
       
  1185 // -----------------------------------------------------------------------------
       
  1186 // CMceSdpSession::IsSessionRefresh
       
  1187 // -----------------------------------------------------------------------------
       
  1188 //
       
  1189 TBool CMceSdpSession::IsSessionRefresh( CSdpDocument* aSdpDocument )
       
  1190     {
       
  1191     TBool isRefresh = EFalse;
       
  1192     
       
  1193     if ( aSdpDocument )
       
  1194         {
       
  1195         iSdpDocument = aSdpDocument;
       
  1196         }
       
  1197 
       
  1198     if ( iSdpDocument )
       
  1199         {
       
  1200         CSdpOriginField* origin = iSdpDocument->OriginField();
       
  1201         if( origin && iRemoteOrigin && *iRemoteOrigin == *origin )
       
  1202             {
       
  1203             isRefresh = CompareMediaLines( iSdpRemoteMediaFields, 
       
  1204             								iSdpDocument->MediaFields() );
       
  1205             }
       
  1206         }
       
  1207         
       
  1208     return isRefresh;
       
  1209     }    
       
  1210 
       
  1211 // -----------------------------------------------------------------------------
       
  1212 // CMceSdpSession::CompareMediaLines
       
  1213 // -----------------------------------------------------------------------------
       
  1214 //
       
  1215 TBool CMceSdpSession::CompareMediaLines( 
       
  1216     RPointerArray<CSdpMediaField>& aFieldsSrc,
       
  1217     RPointerArray<CSdpMediaField>& aFieldsDst ) const
       
  1218     {
       
  1219     TBool result = EFalse;
       
  1220     TInt srcCount = aFieldsSrc.Count();
       
  1221     TInt dstCount = aFieldsDst.Count();
       
  1222     
       
  1223     // Return if count of media fields are not equal.
       
  1224     if ( srcCount == dstCount )
       
  1225         {
       
  1226         result = ETrue;
       
  1227         
       
  1228         // Return if every media field from source array 
       
  1229         // cannot be found from destination array.
       
  1230         for ( TInt i = 0; i < srcCount && result; i++ )
       
  1231             {
       
  1232             result = EFalse;
       
  1233             for ( TInt j = 0; j < dstCount && !result; j++ )
       
  1234                 {
       
  1235                 if ( *aFieldsSrc[i] == *aFieldsDst[j] )
       
  1236                     {
       
  1237                     result = ETrue;
       
  1238                     }
       
  1239 				}
       
  1240             }   
       
  1241         }
       
  1242     
       
  1243     return result;
       
  1244     }
       
  1245         
       
  1246 // -----------------------------------------------------------------------------
       
  1247 // CMceSdpSession::PrepareSessionRefreshL
       
  1248 // -----------------------------------------------------------------------------
       
  1249 //
       
  1250 void CMceSdpSession::PrepareSessionRefreshL( CMceComSession& aSession )
       
  1251     {
       
  1252     User::LeaveIfNull( iSdpDocument );
       
  1253     EncodeSessionParamsL( aSession, *iSdpDocument );
       
  1254     }
       
  1255 
       
  1256 // -----------------------------------------------------------------------------
       
  1257 // CMceSdpSession::SdpCleanup
       
  1258 // -----------------------------------------------------------------------------
       
  1259 //
       
  1260 void CMceSdpSession::SdpCleanup(
       
  1261     CSdpDocument* aPrevious, 
       
  1262     CSdpDocument* aReplacement )
       
  1263     {
       
  1264     if ( iSdpDocument && iSdpDocument == aPrevious )
       
  1265         {
       
  1266         MCEMM_DEBUG("CMceSdpSession::SdpCleanup(), replacing")
       
  1267         iSdpDocument = aReplacement;
       
  1268         }
       
  1269     }
       
  1270     
       
  1271 // -----------------------------------------------------------------------------
       
  1272 // CMceSdpSession::GetRandomNumber
       
  1273 // -----------------------------------------------------------------------------
       
  1274 //
       
  1275 TInt64 CMceSdpSession::GetRandomNumber()
       
  1276     {
       
  1277     TTime currentTime;
       
  1278     currentTime.HomeTime();
       
  1279     TInt64 value( currentTime.Int64() );
       
  1280     return value;
       
  1281     }  
       
  1282     
       
  1283 // -----------------------------------------------------------------------------
       
  1284 // CMceSdpSession::NeedToNegotiate
       
  1285 // -----------------------------------------------------------------------------
       
  1286 //
       
  1287 TBool CMceSdpSession::NeedToNegotiate( CMceComSession& aSession )
       
  1288     {
       
  1289     TBool needToNegotiate = EFalse;
       
  1290     
       
  1291     RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
       
  1292     
       
  1293     TInt index = 0;
       
  1294     while( !needToNegotiate && index < streams.Count() )
       
  1295         {
       
  1296         CMceComMediaStream* stream = streams[ index++ ];
       
  1297         for( int i = 0; i < stream->Preconditions().Count(); i++ )
       
  1298         	{
       
  1299         	needToNegotiate = stream->Preconditions().Count() && 
       
  1300                           !stream->Preconditions()[i]->IsMet();
       
  1301         	}
       
  1302         }
       
  1303         
       
  1304     return needToNegotiate; 
       
  1305     }
       
  1306 
       
  1307 // -----------------------------------------------------------------------------
       
  1308 // CMceSdpSession::ReservationNeeded
       
  1309 // -----------------------------------------------------------------------------
       
  1310 //  
       
  1311 TBool CMceSdpSession::ReservationNeeded( CMceComSession& aSession )
       
  1312     {
       
  1313     TBool reservationNeeded = EFalse;
       
  1314     
       
  1315     RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
       
  1316     
       
  1317     TInt index = 0;
       
  1318     while( !reservationNeeded && index < streams.Count() )
       
  1319         {
       
  1320         CMceComMediaStream* stream = streams[ index++ ];
       
  1321         for( int i = 0; i < stream->Preconditions().Count(); i++ )
       
  1322         	{
       
  1323         	reservationNeeded = ( stream->Preconditions().Count() && 
       
  1324                               stream->Preconditions()[i]->IsMet() ) ? EFalse : ETrue;
       
  1325         	}
       
  1326         }
       
  1327         
       
  1328     return reservationNeeded;
       
  1329     }
       
  1330 
       
  1331 // -----------------------------------------------------------------------------
       
  1332 // CMceSdpSession::ReserveL
       
  1333 // -----------------------------------------------------------------------------
       
  1334 // 
       
  1335 TMceReturnStatus CMceSdpSession::ReserveL( CMceComSession& aSession )
       
  1336     {
       
  1337     //fake implementation    
       
  1338     TMceReturnStatus status = KMceReady;
       
  1339     
       
  1340     RPointerArray<CMceComMediaStream>& streams = aSession.Streams();
       
  1341     
       
  1342     TInt index = 0;
       
  1343     while( index < streams.Count() )
       
  1344         {
       
  1345         CMceComMediaStream* stream = streams[ index++ ];
       
  1346         if ( stream->Preconditions().Count() )
       
  1347             {
       
  1348             for( int i = 0; i < stream->Preconditions().Count(); i++ )
       
  1349         		{
       
  1350             	stream->Preconditions()[ i ]->Reserved();
       
  1351         		}
       
  1352             }
       
  1353         }
       
  1354         
       
  1355     return status;
       
  1356     }
       
  1357 
       
  1358 // -----------------------------------------------------------------------------
       
  1359 // CMceSdpSession::EncodeClientAttributesL
       
  1360 // -----------------------------------------------------------------------------
       
  1361 //
       
  1362 void CMceSdpSession::EncodeClientAttributesL( 
       
  1363     CMceComSession& aSession,
       
  1364     CSdpDocument& aDocument ) const
       
  1365     {
       
  1366     MCEMM_DEBUG("CMceSdpSession::EncodeClientAttributesL, Entry ")
       
  1367     CDesC8Array* clientAttributes = aSession.iLocalSessionSDPLines;
       
  1368     __ASSERT_ALWAYS( clientAttributes, User::Leave( KErrArgument ) );
       
  1369     
       
  1370     CMceSdpCodec::EncodeClientSdpFieldsL<CSdpDocument>( *clientAttributes, aDocument );
       
  1371         
       
  1372     MCEMM_DEBUG("CMceSdpSession::EncodeClientAttributesL, Exit ")
       
  1373     }    
       
  1374 
       
  1375 // -----------------------------------------------------------------------------
       
  1376 // CMceSdpSession::DecodeClientAttributesL
       
  1377 // -----------------------------------------------------------------------------
       
  1378 //
       
  1379 void CMceSdpSession::DecodeClientAttributesL( 
       
  1380     CSdpDocument& aDocument, 
       
  1381     CMceComSession& aSession ) const
       
  1382     {
       
  1383     MCEMM_DEBUG("CMceSdpSession::DecodeClientAttributesL, Entry ")
       
  1384     CDesC8Array* remoteAttributes = 
       
  1385         new (ELeave) CDesC8ArrayFlat( KMceArrayGranularity );
       
  1386     CleanupStack::PushL( remoteAttributes );
       
  1387     
       
  1388     CBufFlat* encodeBuf = NULL;
       
  1389     
       
  1390     for ( TInt i = 0; i < aDocument.AttributeFields().Count(); i++ )
       
  1391         {
       
  1392         
       
  1393     	encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
       
  1394     	CleanupStack::PushL( encodeBuf );
       
  1395     	RBufWriteStream writeStream( *encodeBuf, 0 );
       
  1396 	    writeStream.PushL();
       
  1397         
       
  1398         aDocument.AttributeFields()[ i ]->EncodeL( writeStream );
       
  1399         MCEMM_DEBUG_SVALUE("found attribute", encodeBuf->Ptr( 0 ) )
       
  1400         remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) );
       
  1401     	
       
  1402     	CleanupStack::PopAndDestroy(); // writeStream
       
  1403         CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf
       
  1404         }
       
  1405 
       
  1406     for ( TInt i = 0; i < aDocument.BandwidthFields().Count(); i++ )
       
  1407         {
       
  1408         
       
  1409     	encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize );
       
  1410     	CleanupStack::PushL( encodeBuf );
       
  1411     	RBufWriteStream writeStream( *encodeBuf, 0 );
       
  1412 	    writeStream.PushL();
       
  1413         
       
  1414         aDocument.BandwidthFields()[ i ]->EncodeL( writeStream );
       
  1415         MCEMM_DEBUG_SVALUE("found attribute", encodeBuf->Ptr( 0 ) )
       
  1416         remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) );
       
  1417     	
       
  1418     	CleanupStack::PopAndDestroy(); // writeStream
       
  1419         CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf
       
  1420         }
       
  1421     
       
  1422     CleanupStack::Pop( remoteAttributes );
       
  1423     MCE_DELETE( aSession.iRemoteSessionSDPLines );
       
  1424     aSession.iRemoteSessionSDPLines = remoteAttributes;
       
  1425     MCEMM_DEBUG("CMceSdpSession::DecodeClientAttributesL, Exit ")
       
  1426     }
       
  1427 
       
  1428 // -----------------------------------------------------------------------------
       
  1429 // CMceSdpSession::Consumes
       
  1430 // -----------------------------------------------------------------------------
       
  1431 //
       
  1432 CMceComSession* CMceSdpSession::Consumes( TUint32 aSessionId )
       
  1433     {
       
  1434     CMceComSession* session = MediaSession();
       
  1435     CMceComSession* backup = Backup();
       
  1436     CMceComSession* foundSession = NULL;
       
  1437 
       
  1438     foundSession = ( session && 
       
  1439                      session->iMccID != KMceNotAssigned &&
       
  1440                      session->iMccID == aSessionId ) ? 
       
  1441                         session :
       
  1442                       ( backup &&
       
  1443                         backup->iMccID != KMceNotAssigned &&
       
  1444                         backup->iMccID == aSessionId ) ? 
       
  1445                             backup :
       
  1446                             NULL;
       
  1447     
       
  1448     return foundSession;
       
  1449     }
       
  1450 
       
  1451 // -----------------------------------------------------------------------------
       
  1452 // CMceSdpSession::StockMediaSessionL
       
  1453 // -----------------------------------------------------------------------------
       
  1454 //
       
  1455 void CMceSdpSession::StockMediaSessionL()
       
  1456     {
       
  1457     MCEMM_DEBUG("CMceSdpSession::StockMediaSessionL, Entry ")
       
  1458     
       
  1459     if ( !iInitialSession && !Backup() )
       
  1460         {
       
  1461         iInitialSession = MediaSession()->CloneL();
       
  1462         MCEMM_DEBUG("Stocked")
       
  1463         }
       
  1464         
       
  1465     MCEMM_DEBUG("CMceSdpSession::StockMediaSessionL, Exit ")
       
  1466     }
       
  1467 
       
  1468 
       
  1469 // -----------------------------------------------------------------------------
       
  1470 // CMceSdpSession::ForkL
       
  1471 // -----------------------------------------------------------------------------
       
  1472 //
       
  1473 CMceSdpSession& CMceSdpSession::ForkL()
       
  1474     {
       
  1475     MCEMM_DEBUG("CMceSdpSession::ForkL, Entry ")
       
  1476     
       
  1477     __ASSERT_ALWAYS( MediaSession(), User::Leave( KErrArgument ) );
       
  1478     __ASSERT_ALWAYS( IsMaster(), User::Leave( KErrArgument ) );
       
  1479     __ASSERT_ALWAYS( !Backup(), User::Leave( KErrArgument ) );
       
  1480     __ASSERT_ALWAYS( iInitialSession, User::Leave( KErrArgument ) );
       
  1481 
       
  1482     CMceComSession* forkedMediaSession = 
       
  1483         iInitialSession->CloneAndMergeLC( *MediaSession() );
       
  1484     CMceSdpSession& forkedSession = Manager().CreateSessionL( *forkedMediaSession );
       
  1485 
       
  1486     ContextSwitch( &forkedSession );
       
  1487     
       
  1488     MediaSession()->MediaObserver().SessionCreatedL( forkedMediaSession );
       
  1489     CleanupStack::Pop( forkedMediaSession );
       
  1490         
       
  1491     MCEMM_DEBUG("CMceSdpSession::ForkL, Exit ")
       
  1492     
       
  1493     return forkedSession;   
       
  1494     }
       
  1495 
       
  1496 // -----------------------------------------------------------------------------
       
  1497 // CMceSdpSession::IsMaster
       
  1498 // -----------------------------------------------------------------------------
       
  1499 //
       
  1500 TBool CMceSdpSession::IsMaster()
       
  1501     {
       
  1502     return iIsMaster;
       
  1503     }
       
  1504 
       
  1505 // -----------------------------------------------------------------------------
       
  1506 // CMceSdpSession::ContextSwitch
       
  1507 // -----------------------------------------------------------------------------
       
  1508 //
       
  1509 void CMceSdpSession::ContextSwitch( CMceSdpSession* aForkedSession )
       
  1510     {
       
  1511     MCEMM_DEBUG("CMceSdpSession::ContextSwitch, Entry ")
       
  1512     
       
  1513     CMceSdpSession* oldMaster = this;
       
  1514     CMceSdpSession* newMaster = aForkedSession;
       
  1515     
       
  1516     if ( !newMaster && !oldMaster->IsMaster() )
       
  1517         {
       
  1518         newMaster = this;
       
  1519         oldMaster = NULL;
       
  1520         CMceSdpSession::TIterator 
       
  1521                 masterCandidates( Manager().iMceSdpSessions, 
       
  1522                                   CMceSdpSession::TIterator::EFilterMaster );
       
  1523 
       
  1524         MCE_ITERATOR_FIND_NEXT( masterCandidates, oldMaster,
       
  1525                                 oldMaster->MediaSession()->iMccID ==
       
  1526                                 newMaster->MediaSession()->iMccID );
       
  1527                                 
       
  1528         }
       
  1529 
       
  1530     if ( oldMaster && newMaster )
       
  1531         {
       
  1532         newMaster->iIsMaster = ETrue;
       
  1533         oldMaster->iIsMaster = EFalse;
       
  1534         delete newMaster->iInitialSession;
       
  1535         newMaster->iInitialSession = oldMaster->iInitialSession;
       
  1536         oldMaster->iInitialSession = NULL;
       
  1537         newMaster->iContext = oldMaster->iRequestedContext ? 
       
  1538                               oldMaster->iRequestedContext :
       
  1539                               newMaster->iContext;
       
  1540         newMaster->iRequestedContext = NULL;
       
  1541         oldMaster->iRequestedContext = NULL;
       
  1542 
       
  1543         newMaster->MediaSession()->Merge( *oldMaster->MediaSession(), 
       
  1544                                           KMceDeepMergeYes );
       
  1545         
       
  1546         MCEMM_DEBUG("context switch performed")
       
  1547         }
       
  1548     else
       
  1549         {
       
  1550         MCEMM_DEBUG("no context switch performed!!")
       
  1551         }
       
  1552 
       
  1553     MCEMM_DEBUG("CMceSdpSession::ContextSwitch, Exit ")
       
  1554     }
       
  1555 
       
  1556 // -----------------------------------------------------------------------------
       
  1557 // CMceSdpSession::ContextSwitchRequested
       
  1558 // -----------------------------------------------------------------------------
       
  1559 //
       
  1560 TBool CMceSdpSession::ContextSwitchRequested()
       
  1561     {
       
  1562     return iContext && iRequestedContext && iRequestedContext != iContext;
       
  1563     }
       
  1564 
       
  1565 // -----------------------------------------------------------------------------
       
  1566 // CMceSdpSession::Context
       
  1567 // -----------------------------------------------------------------------------
       
  1568 //
       
  1569 CSIPDialogAssocBase* CMceSdpSession::Context()
       
  1570     {
       
  1571     return iContext;
       
  1572     }
       
  1573 
       
  1574 // -----------------------------------------------------------------------------
       
  1575 // CMceSdpSession::AttachContext
       
  1576 // -----------------------------------------------------------------------------
       
  1577 //
       
  1578 void CMceSdpSession::AttachContext( CSIPDialogAssocBase* aContext )
       
  1579     {
       
  1580     if ( !iContext || !aContext )
       
  1581         {
       
  1582         iContext = aContext;
       
  1583         }
       
  1584     else if ( aContext != iContext )
       
  1585         {
       
  1586         iRequestedContext = aContext;
       
  1587         }
       
  1588     else
       
  1589         {
       
  1590         iRequestedContext = NULL;
       
  1591         }
       
  1592     }
       
  1593 
       
  1594 // -----------------------------------------------------------------------------
       
  1595 // CMceSdpSession::TIterator::TIterator
       
  1596 // -----------------------------------------------------------------------------
       
  1597 //
       
  1598 CMceSdpSession::TIterator::TIterator( 
       
  1599     RPointerArray<CMceSdpSession>& aCodecs, 
       
  1600     CMceSdpSession::TIterator::TFilter aFilter )
       
  1601     : iFilter( aFilter ),
       
  1602       iSessions( aCodecs ),
       
  1603       iCurrentIndex( 0 )
       
  1604     {
       
  1605     }
       
  1606 
       
  1607 // -----------------------------------------------------------------------------
       
  1608 // CMceSdpSession::TIterator::IsEof
       
  1609 // -----------------------------------------------------------------------------
       
  1610 //
       
  1611 TBool CMceSdpSession::TIterator::IsEof()
       
  1612     {
       
  1613     return iSessions.Count() == 0 || iCurrentIndex >= iSessions.Count();
       
  1614     }          
       
  1615 
       
  1616 // -----------------------------------------------------------------------------
       
  1617 // CMceSdpSession::TIterator::Next
       
  1618 // -----------------------------------------------------------------------------
       
  1619 //
       
  1620 TBool CMceSdpSession::TIterator::Next( CMceSdpSession*& aCandidate )
       
  1621     {
       
  1622     CMceSdpSession* next = NULL;
       
  1623     
       
  1624     while( !next && !IsEof() )
       
  1625         {
       
  1626         CMceSdpSession* session = iSessions[ iCurrentIndex ];
       
  1627         TBool condition = EFalse;
       
  1628         switch( iFilter )
       
  1629             {
       
  1630             case EFilterMaster:
       
  1631                 {
       
  1632                 condition = session->IsMaster();
       
  1633                 break;
       
  1634                 }
       
  1635             default:
       
  1636                 {
       
  1637                 condition = ETrue;
       
  1638                 break;
       
  1639                 }
       
  1640             }
       
  1641 
       
  1642         next = condition ? session : NULL;
       
  1643                
       
  1644         iCurrentIndex++;
       
  1645         }
       
  1646 
       
  1647     aCandidate = next;
       
  1648     return aCandidate ? ETrue : EFalse;  
       
  1649     }
       
  1650     
       
  1651 // -----------------------------------------------------------------------------
       
  1652 // CMceSdpSession::Current
       
  1653 // -----------------------------------------------------------------------------
       
  1654 //
       
  1655 TInt CMceSdpSession::TIterator::Current()
       
  1656     {
       
  1657     TInt current = KErrNotFound;
       
  1658     
       
  1659     if ( iSessions.Count() > 0 )
       
  1660         {
       
  1661         current = iCurrentIndex-1;
       
  1662         current = current < 0 ? 0 : current;
       
  1663         }
       
  1664     return current;
       
  1665     }
       
  1666     
       
  1667 // -----------------------------------------------------------------------------
       
  1668 // CMceSdpSession::Remove
       
  1669 // -----------------------------------------------------------------------------
       
  1670 //
       
  1671 TInt CMceSdpSession::TIterator::Remove()
       
  1672     {  
       
  1673     TInt current = Current();
       
  1674     
       
  1675     if ( current != KErrNotFound )
       
  1676         {
       
  1677         iSessions.Remove( current );
       
  1678         iCurrentIndex = current;
       
  1679         }
       
  1680     
       
  1681     return current;
       
  1682     }
       
  1683     
       
  1684 // -----------------------------------------------------------------------------
       
  1685 // CMceSdpSession::TIterator::Reset
       
  1686 // -----------------------------------------------------------------------------
       
  1687 //
       
  1688 void CMceSdpSession::TIterator::Reset()
       
  1689     {
       
  1690     iCurrentIndex = 0;
       
  1691     }
       
  1692             
       
  1693 // -----------------------------------------------------------------------------
       
  1694 // CMceSdpSession::TIterator::SetFilter
       
  1695 // -----------------------------------------------------------------------------
       
  1696 //
       
  1697 void CMceSdpSession::TIterator::SetFilter( 
       
  1698     CMceSdpSession::TIterator::TFilter aFilter )
       
  1699     {
       
  1700     iFilter = aFilter;
       
  1701     }
       
  1702             
       
  1703 // -----------------------------------------------------------------------------
       
  1704 // CMceSdpSession::TIterator::Count
       
  1705 // -----------------------------------------------------------------------------
       
  1706 //
       
  1707 TInt CMceSdpSession::TIterator::Count()
       
  1708     {
       
  1709     TInt count = iSessions.Count();
       
  1710     if ( iFilter )
       
  1711         {
       
  1712         TInt currentIndex = iCurrentIndex;
       
  1713         Reset();
       
  1714         CMceSdpSession* codec = NULL;
       
  1715         count = 0;
       
  1716         while( Next( codec ) )
       
  1717             {
       
  1718             count++;
       
  1719             }
       
  1720         iCurrentIndex = currentIndex;
       
  1721         }
       
  1722 
       
  1723     return count;
       
  1724     }