multimediacommscontroller/mmccrtpsourcesink/src/mccrtpdatasource.cpp
changeset 0 1bce908db942
child 32 f2ed1fc4c163
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:    RTP Datasource
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <in_sock.h>
       
    23 #include <mmf/common/mmfcontroller.h>
       
    24 
       
    25 #include "rtpapi.h"
       
    26 #include "mccrtpdatasource.h"
       
    27 #include "mccinternalevents.h"
       
    28 #include "formatstatemachine.h"
       
    29 #include "mccrtpdefs.h"
       
    30 #include "mmccinterfacedef.h"
       
    31 #include "mcctimermanager.h"
       
    32 
       
    33 #include <srtpcryptocontext.h>
       
    34 #include <srtpstreamin.h>
       
    35 
       
    36 // MACROS
       
    37 #define MCC_RTPSOURCE_ENDPOINT_ID reinterpret_cast<TUint32>( static_cast<MDataSource*>( this ) )
       
    38 
       
    39 
       
    40 // ============================= LOCAL FUNCTIONS ===============================
       
    41 
       
    42 // ============================ MEMBER FUNCTIONS ===============================
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CMccRtpDataSource::CMccRtpDataSource
       
    46 // C++ default constructor can NOT contain any code, that
       
    47 // might leave.
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 CMccRtpDataSource::CMccRtpDataSource() : 
       
    51     CMccDataSource( KMccRtpSourceUid ),
       
    52     MMccRtpInterface(),
       
    53     iStandByTimerValue( KRtpStandByTimer ),
       
    54     iRtpStreamId( KNullId ),
       
    55     iInactivityTimerId( KMaxTUint32 )
       
    56     {
       
    57     iCurRecvPayloadType = KMccPTNotDefined;
       
    58     }
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CMccRtpDataSource::ConstructSourceL
       
    62 // Symbian 2nd phase constructor can leave.
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 void CMccRtpDataSource::ConstructSourceL( const TDesC8& aInitData )
       
    66     {
       
    67     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ConstructSourceL" )
       
    68 
       
    69     SetStateL( ERtpStateConstructed );
       
    70  
       
    71     TMccRtpSourceSetting rtpSettings;
       
    72     rtpSettings.iStandByTimerValue = 200;
       
    73     TMccRtpSourceSettingBuf rtpSettingsBuf( rtpSettings );
       
    74     
       
    75     if ( aInitData.Length() > 0)
       
    76 	    {
       
    77 	   	TMccRtpSourceSettingBuf settingsBuf;
       
    78 		settingsBuf.Copy( aInitData );
       
    79 		iStandByTimerValue = settingsBuf().iStandByTimerValue;
       
    80 	    }
       
    81     
       
    82     iTimer = CMccTimerManager::NewL();
       
    83     
       
    84     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::ConstructSourceL iStandByTimerValue %d",
       
    85         iStandByTimerValue )
       
    86     }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CMccRtpDataSource::NewSourceL
       
    90 // Static constructor.
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 MDataSource* CMccRtpDataSource::NewSourceL( TUid /*aImplementationUid*/, 
       
    94                                             const TDesC8& /*aInitData*/ )
       
    95     {
       
    96     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::NewSourceL" )
       
    97 
       
    98     CMccRtpDataSource* self = new ( ELeave ) CMccRtpDataSource();
       
    99     return static_cast<MDataSource*>( self );
       
   100     }
       
   101 
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CMccRtpDataSource::~CMccRtpDataSource()
       
   105 // Destructor.
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 CMccRtpDataSource::~CMccRtpDataSource()
       
   109     {
       
   110     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::~CMccRtpDataSource 0x%x", this )
       
   111 
       
   112     iBufferToFill = NULL;
       
   113     iEventHandler = NULL;
       
   114     iFillBufferRequester = NULL;
       
   115 
       
   116     CloseStreams();
       
   117     iUsers.Close();
       
   118     
       
   119     delete iTimer;
       
   120     delete iJitCalc;
       
   121     
       
   122     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::~CMccRtpDataSource OUT" )
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // CMccRtpDataSource::FillBufferL
       
   127 // FillBufferL works synchronously.
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 void CMccRtpDataSource::FillBufferL( CMMFBuffer* aBuffer, 
       
   131                                      MDataSink*  aConsumer, 
       
   132                                      TMediaId    /*aMediaId*/ )
       
   133     {    
       
   134     TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::FillBufferL" )
       
   135     
       
   136     // Sink might want to indicate pause/stop by passing NULL buffer
       
   137     if ( aBuffer )
       
   138         {
       
   139         __ASSERT_ALWAYS ( aConsumer, User::Leave( KErrArgument ) );
       
   140         __ASSERT_ALWAYS ( KUidMmfDataBuffer == aBuffer->Type( ), 
       
   141         User::Leave( KErrNotSupported ) );
       
   142         }
       
   143         
       
   144     iBufferToFill = static_cast<CMMFDataBuffer*>( aBuffer );
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CMccRtpDataSource::CanCreateSourceBuffer
       
   149 // NOT SUPPORTED. MDataSource pure virtual function must to be implemented.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 TBool CMccRtpDataSource::CanCreateSourceBuffer()
       
   153     {
       
   154     return EFalse;
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CMccRtpDataSource::CreateSourceBufferL
       
   159 // NOT SUPPORTED. MDataSource pure virtual function must to be implemented.
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 CMMFBuffer* CMccRtpDataSource::CreateSourceBufferL( TMediaId /*aMediaId*/,
       
   163                                                     TBool& /*aReference*/ )
       
   164     {
       
   165     TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::CreateSourceBufferL KErrNotSupported" )
       
   166     
       
   167     User::Leave( KErrNotSupported );
       
   168     return NULL;
       
   169     }
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 // CMccRtpDataSource::RtpPacketReceived
       
   173 // RTP stack callback function for received RTP packet.
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 void CMccRtpDataSource::RtpPacketReceived( TRtpId aStreamId, 
       
   177                                            const TRtpRecvHeader& aHeaderInfo, 
       
   178                                            const TDesC8& aPayloadData )
       
   179 	{
       
   180     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceived iSecureKeyExpired: %d",
       
   181         iSecureKeyExpired )
       
   182     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceived iPayloadType: %u",
       
   183         aHeaderInfo.iPayloadType )
       
   184         
       
   185     // Filter out also bogus payload types here. NB; should something be done
       
   186     // for the trapped errorcode and bogus RTP packets. Though they should not
       
   187     // reach this point.
       
   188 	if ( !iSecureKeyExpired &&
       
   189 	     aHeaderInfo.iPayloadType < KPayloadTypeUndefined )
       
   190 		{
       
   191 		TRAP_IGNORE( RtpPacketReceivedL( aStreamId, aHeaderInfo, aPayloadData ) )
       
   192 		}
       
   193 	}
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 // CMccRtpDataSource::RtpPacketReceivedL
       
   197 // RTP stack callback function for received RTP packet.
       
   198 // -----------------------------------------------------------------------------
       
   199 //
       
   200 void CMccRtpDataSource::RtpPacketReceivedL( TRtpId aStreamId, 
       
   201                                            const TRtpRecvHeader& aHeaderInfo, 
       
   202                                            const TDesC8& aPayloadData )
       
   203     {
       
   204     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL DATALEN: %d",
       
   205         aPayloadData.Length() )
       
   206     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL ASTREAM: %d",
       
   207         aStreamId )
       
   208     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL ISTREAM: %d",
       
   209         iRtpStreamId )
       
   210     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL SEQ_NUM: %d",
       
   211         aHeaderInfo.iSeqNum )
       
   212     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL T_STAMP: %d",
       
   213         aHeaderInfo.iTimestamp )
       
   214     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL MARKER: %d",
       
   215         aHeaderInfo.iMarker )
       
   216     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL STATE: %d",
       
   217         State() )
       
   218     
       
   219     if ( ERtpStatePlaying == State() )
       
   220         {
       
   221         __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) );
       
   222         __ASSERT_ALWAYS( iFillBufferRequester, User::Leave( KErrNotReady ) );
       
   223         
       
   224         TMccRtpUser* currentUser = ValidatePacketL( aStreamId, aHeaderInfo, aPayloadData );
       
   225         TBool isCN = EFalse;
       
   226         
       
   227         // Change the main receive PT only if it is not CN.
       
   228         if ( KCnPayloadType != aHeaderInfo.iPayloadType &&
       
   229              KCnPayloadTypeReserved != aHeaderInfo.iPayloadType )
       
   230             {
       
   231             iCurRecvPayloadType = aHeaderInfo.iPayloadType;
       
   232             }
       
   233         else
       
   234             {
       
   235             isCN = ETrue;
       
   236             }
       
   237         
       
   238         if ( InactivityTimerActive() )
       
   239             {
       
   240             TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::resetting inactivity timer" )
       
   241             
       
   242             StartInactivityTimerL( iTimeoutTime );
       
   243             }
       
   244         
       
   245         // Note that ValidataPacketL may return a NULL ptr, thus guard against
       
   246         // it.
       
   247         if ( currentUser )
       
   248             {
       
   249   		    StartRtpStandByTimerL( currentUser );
       
   250   		    DoStandByDecision( currentUser );
       
   251             }
       
   252         
       
   253         // Do jitter calculations
       
   254         if ( iJitCalc->IsObserving() )
       
   255             {
       
   256             iJitCalc->RtpPacketReceived( aHeaderInfo.iTimestamp,
       
   257                                          aHeaderInfo.iMarker );
       
   258             }
       
   259             
       
   260         // First packet after SourcePlayL, notify event handler by sending
       
   261         // the event.
       
   262         if ( !iDlStreamStarted )
       
   263             {
       
   264             iDlStreamStarted = ETrue;
       
   265             SendInternalRtpEventToClient( iEventHandler,
       
   266                                           KMccRtpSourceUid, 
       
   267                                           KMccInternalRtpSrcMmfEvent, 
       
   268                                           KMccActivityEvent,
       
   269                                           MCC_RTPSOURCE_ENDPOINT_ID );
       
   270             }
       
   271         
       
   272         // CN is not currently sent forward to decoding and playback. It
       
   273         // causes problems with jitterbuffering and results into a degraded
       
   274         // audio quality.
       
   275         if ( !isCN )
       
   276             {
       
   277             TRAPD( err, PlayoutRtpPacketL( aHeaderInfo, aPayloadData ) )
       
   278             
       
   279             // Notify the event handler about error cases so appropriate
       
   280             // actions can be taken.
       
   281             if ( KErrNone != err )
       
   282                 {
       
   283                 SendInternalRtpEventToClient( iEventHandler,
       
   284                                               KMccRtpSourceUid,
       
   285                                               KMccInternalRtpSrcMmfEvent,
       
   286                                               KMccStreamError,
       
   287                                               MCC_RTPSOURCE_ENDPOINT_ID,
       
   288                                               err );
       
   289                 }
       
   290             }
       
   291 		}
       
   292     }
       
   293 
       
   294 // -----------------------------------------------------------------------------
       
   295 // CMccRtpDataSource::SetSourceDataTypeCode
       
   296 // Sets the sources datatype code ( Codec )
       
   297 // -----------------------------------------------------------------------------
       
   298 //
       
   299 TInt CMccRtpDataSource::SetSourceDataTypeCode( TFourCC aCodec, TMediaId /*aMedia*/ )
       
   300     {
       
   301     iCodecInfo.iFourCC = aCodec;
       
   302     return KErrNone;
       
   303     }
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // CMccRtpDataSource::SourceDataTypeCode()
       
   307 // Sets the datatype code ( codec )
       
   308 // -----------------------------------------------------------------------------
       
   309 //
       
   310 TFourCC CMccRtpDataSource::SourceDataTypeCode( TMediaId /*aMediaId*/ )
       
   311     {
       
   312     return iCodecInfo.iFourCC;
       
   313     }
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CMccRtpDataSource::BufferEmptiedL
       
   317 // CMccRtpDataSource supports only passive mode of operation. 
       
   318 // Thus, Datapath->EmptyBufferL isn't called.
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 void CMccRtpDataSource::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
       
   322     {
       
   323     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::BufferEmptiedL KErrNotSupported" )
       
   324     
       
   325     User::Leave( KErrNotSupported );
       
   326     }
       
   327 
       
   328 // -----------------------------------------------------------------------------
       
   329 // CMccRtpDataSource::SourceThreadLogon
       
   330 //
       
   331 // Method to 'logon' the data source to the same thread that source will be 
       
   332 // consuming data in. Thread specific initialisation is done here.
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 TInt CMccRtpDataSource::SourceThreadLogon( MAsyncEventHandler& aEventHandler )
       
   336     {
       
   337     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogon" )
       
   338     
       
   339     TInt err( KErrNone );
       
   340     
       
   341     iEventHandler = &aEventHandler;
       
   342     if ( NULL == iJitCalc )
       
   343         {
       
   344         TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogon,\
       
   345             create jitter calculator" )
       
   346         TRAP( err, iJitCalc = CMccJitterCalculator::NewL( *this ) );
       
   347         }
       
   348     
       
   349     return err;
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CMccRtpDataSource::SourceThreadLogoff
       
   354 //
       
   355 // Method to 'logoff' the data source from the same thread that source consumes 
       
   356 // data in. Thread specific releasing of resources is done here.
       
   357 // -----------------------------------------------------------------------------
       
   358 //
       
   359 void CMccRtpDataSource::SourceThreadLogoff()
       
   360     {
       
   361     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogoff" )
       
   362     StopKeepalive();
       
   363 
       
   364     iEventHandler = NULL;
       
   365 
       
   366     // Close the streams (if any)
       
   367     if ( KNullId != iRtpStreamId )
       
   368         {
       
   369         iRtpAPI->UnregisterRtpObserver( iSessionID );
       
   370     	}
       
   371     	
       
   372 	CloseStreams();
       
   373     iRtpAPI = NULL;
       
   374     iRtpStreamId = KNullId;
       
   375     
       
   376     iBufferToFill = NULL;
       
   377         
       
   378     delete iTimer;
       
   379     iTimer = NULL;
       
   380 
       
   381     delete iJitCalc;
       
   382     iJitCalc = NULL;
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // CMccRtpDataSource::SourcePrimeL
       
   387 // Source must be primed before playing.
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 void CMccRtpDataSource::SourcePrimeL()
       
   391     {
       
   392     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePrimeL" )
       
   393 
       
   394     SetStateL( ERtpStatePrimed );
       
   395     
       
   396     SendStreamEventToClient( KMccStreamPrepared ); 
       
   397     }
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // CMccRtpDataSource::SourcePlayL
       
   401 // Start receiving RTP packets.
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 void CMccRtpDataSource::SourcePlayL()
       
   405     {
       
   406     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePlayL" )
       
   407     if ( iSecureKeyExpired )
       
   408     	{
       
   409     	TRACE_RTP_SINK_PRINT( "Leave becuase the secure key expired" )
       
   410     	User::Leave( KErrGeneral );
       
   411     	}
       
   412 	//Leave when is the secure evnet key expired and try to restart
       
   413     iPacketsReceived = 0;
       
   414     iDlStreamStarted = EFalse;
       
   415     
       
   416     TSourceSinkState oldState = State();
       
   417     
       
   418     __ASSERT_ALWAYS( iJitCalc, User::Leave( KErrNotFound ) );
       
   419     iJitCalc->ResetCounters();
       
   420     
       
   421     ResetStandBy();
       
   422     
       
   423     SetStateL( ERtpStatePlaying );
       
   424     
       
   425     // Enable keepalive while receiving (depending on codec settings)
       
   426     // Keepalive is not supported in recvonly secure sessions
       
   427     if ( !iSecSession )
       
   428         {
       
   429         StartKeepaliveL( *iRtpMediaClock );
       
   430         }
       
   431     
       
   432     if ( oldState == ERtpStatePaused )
       
   433         {
       
   434         SendStreamEventToClient( KMccStreamResumed ); 
       
   435         }
       
   436     else
       
   437         {
       
   438         SendStreamEventToClient( KMccStreamStarted ); 
       
   439         }
       
   440     }
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CMccRtpDataSource::SourcePauseL
       
   444 // Pause RTP packet receiving.
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 void CMccRtpDataSource::SourcePauseL()
       
   448     {
       
   449     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePauseL" )
       
   450     
       
   451     iPacketsReceived = 0;
       
   452     __ASSERT_ALWAYS( iJitCalc, User::Leave( KErrNotFound ) );
       
   453     iJitCalc->ResetCounters();
       
   454 
       
   455     SetStateL( ERtpStatePaused );
       
   456     
       
   457     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePauseL\
       
   458     stop standby timers" )
       
   459     
       
   460     StopRtpStandByTimers();
       
   461     
       
   462     SendStreamEventToClient( KMccStreamPaused ); 
       
   463     }
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // CMccRtpDataSource::SourceStopL
       
   467 // Stop RTP packet receiving.
       
   468 // -----------------------------------------------------------------------------
       
   469 //
       
   470 void CMccRtpDataSource::SourceStopL()
       
   471     {
       
   472     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceStopL" )
       
   473     
       
   474     iDlStreamStarted = EFalse;
       
   475     SetStateL( ERtpStateStopped );
       
   476     
       
   477     StopKeepalive();
       
   478     
       
   479     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceStopL,\
       
   480     Stop standby timers" )
       
   481     
       
   482     StopRtpStandByTimers();
       
   483     
       
   484     SendStreamEventToClient( KMccStreamStopped ); 
       
   485     }
       
   486 
       
   487 // -----------------------------------------------------------------------------
       
   488 // CMccRtpDataSource::PlayoutRtpPacketL
       
   489 // Pass filled buffer to the data sink of RTP data source.
       
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 void CMccRtpDataSource::PlayoutRtpPacketL( const TRtpRecvHeader& aHeaderInfo, 
       
   493         const TDesC8& aPayloadData )
       
   494     {
       
   495     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::PlayoutRtpPacketL" )
       
   496     __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) );
       
   497     __ASSERT_ALWAYS( iFillBufferRequester, User::Leave( KErrNotReady ) );
       
   498     
       
   499     iBufferToFill->Data().Copy( aPayloadData );
       
   500     
       
   501     CPayloadFormatRead* sink = static_cast<CPayloadFormatRead*>( iFillBufferRequester );
       
   502     User::LeaveIfNull( sink );
       
   503     sink->DataBufferFilledL( iBufferToFill, aHeaderInfo );
       
   504     }
       
   505 
       
   506 
       
   507 // -----------------------------------------------------------------------------
       
   508 // CMccRtpDataSource::DoCreateStreamL
       
   509 // Creates a receive stream.
       
   510 // -----------------------------------------------------------------------------
       
   511 //
       
   512 void CMccRtpDataSource::DoCreateStreamL()
       
   513     {
       
   514     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL IN !!!!" )
       
   515     __ASSERT_ALWAYS( KNullId == iRtpStreamId, User::Leave( KErrAlreadyExists ) );
       
   516     __ASSERT_ALWAYS( NULL != iRtpAPI, User::Leave( KErrNotReady ) );
       
   517     
       
   518     TRcvStreamParams rcvParams;
       
   519     rcvParams.iPayloadType = iCodecInfo.iPayloadType;
       
   520 
       
   521     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoCreateStreamL CONFIGURED_PT: %u",
       
   522         iCodecInfo.iPayloadType )
       
   523     
       
   524     iRtpStreamId = iRtpAPI->CreateReceiveStreamL( iSessionID, rcvParams );
       
   525     if ( KNullId == iRtpStreamId )
       
   526         {
       
   527         TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL KErrCouldNotConnect 1" )
       
   528         
       
   529         User::Leave( KErrCouldNotConnect );
       
   530         }
       
   531     
       
   532     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL SetSamplingRate 1" )
       
   533         
       
   534     User::LeaveIfError( 
       
   535         iRtpAPI->SetSamplingRate( iCodecInfo.iPayloadType, KDefSampleRate ) );
       
   536 
       
   537     if ( KMccPayloadTypeMax != iCodecInfo.iRedundantPayload )
       
   538         {
       
   539         User::LeaveIfError( iRtpAPI->SetSamplingRate( 
       
   540             iCodecInfo.iRedundantPayload, KDefSampleRate ) );
       
   541         }
       
   542     
       
   543     User::LeaveIfError( iRtpAPI->RegisterRtpObserver( iSessionID, *this ) );
       
   544 
       
   545     DoCreateSrtpStreamL();
       
   546     
       
   547     TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL OUT" )
       
   548     }
       
   549 
       
   550 // -----------------------------------------------------------------------------
       
   551 // CMccRtpDataSource::DoCreateSrtpStreamL
       
   552 // -----------------------------------------------------------------------------
       
   553 //
       
   554 void CMccRtpDataSource::DoCreateSrtpStreamL()
       
   555 	{
       
   556 	TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL IN" )
       
   557 	if ( !iSrtpStream && iContext && iSecSession && KNullId != iRtpStreamId )
       
   558         {
       
   559         TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL, creating" )
       
   560         iSrtpStream = CSRTPStreamIn::NewL( *iSecSession, iContext, *this );
       
   561         }
       
   562     TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL OUT" )
       
   563 	}
       
   564 	
       
   565 // -----------------------------------------------------------------------------
       
   566 // CMccRtpDataSource::NegotiateSourceL
       
   567 // Derived from MDataSource
       
   568 // -----------------------------------------------------------------------------
       
   569 //
       
   570 void CMccRtpDataSource::NegotiateSourceL( MDataSink& aDataSink )
       
   571     {
       
   572     iFillBufferRequester = &aDataSink;
       
   573     }
       
   574 
       
   575 // -----------------------------------------------------------------------------
       
   576 // CMccRtpDataSource::SendMediaSignallingL
       
   577 // Derived from CRtpInterface
       
   578 // -----------------------------------------------------------------------------
       
   579 //
       
   580 void CMccRtpDataSource::SendMediaSignallingL( const TMccEvent& aEvent )
       
   581     {
       
   582     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendMediaSignallingL" )
       
   583     	
       
   584     __ASSERT_ALWAYS( aEvent.iEventCategory == KMccEventCategoryRtcp &&
       
   585                      aEvent.iEventType == KMccRtcpControl &&
       
   586                      iEnableRtcp,
       
   587                      User::Leave( KErrNotSupported ) );
       
   588                      
       
   589     __ASSERT_ALWAYS( iRtpAPI, User::Leave( KErrNotReady ) );
       
   590     
       
   591     const TMccRtcpEventData& rtcpEvent = 
       
   592         (*reinterpret_cast<const TMccRtcpEventDataPackage*>( 
       
   593             &aEvent.iEventData ))(); 
       
   594     
       
   595     switch ( rtcpEvent.iRtcpPacketType )
       
   596         {
       
   597         case KRtcpRrPacket:
       
   598             {
       
   599             TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendMediaSignallingL, RR" )
       
   600             
       
   601             __ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) );
       
   602             User::LeaveIfError( iRtpAPI->SendRtcpRrPacket( iRtpStreamId ) );
       
   603             break;
       
   604             } 
       
   605         default:
       
   606             {
       
   607             User::Leave( KErrArgument );
       
   608             break;
       
   609             }
       
   610         }
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CMccRtpDataSource::StartInactivityTimer
       
   615 // Starts inactivity timer for a stream 
       
   616 // -----------------------------------------------------------------------------
       
   617 //
       
   618 void CMccRtpDataSource::StartInactivityTimerL( TUint32 aTimeoutTime )
       
   619     {
       
   620     TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StartInactivityTimerL" )
       
   621     
       
   622     if( aTimeoutTime == 0 )
       
   623         {
       
   624         User::Leave( KErrArgument );
       
   625         }
       
   626         
       
   627     iTimeoutTime = aTimeoutTime;
       
   628     
       
   629     StopInactivityTimerL();
       
   630     
       
   631     iInactivityTimerId = iTimer->StartL( this, aTimeoutTime );
       
   632     
       
   633     TRACE_RTP_SOURCE_PRINT2 ( "CMccRtpDataSource::StartInactivityTimerL, timer id: %d", 
       
   634                               iInactivityTimerId )
       
   635     
       
   636     TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StartInactivityTimerL, Exit" )
       
   637     }
       
   638 
       
   639 // -----------------------------------------------------------------------------
       
   640 // CMccRtpDataSource::StopInactivityTimer
       
   641 // Stops inactivity timer for a stream
       
   642 // -----------------------------------------------------------------------------
       
   643 //
       
   644 void CMccRtpDataSource::StopInactivityTimerL()
       
   645     {
       
   646     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StopInactivityTimerL" )
       
   647 
       
   648     // It does not matter whether timer is active or not
       
   649     iTimer->Stop( iInactivityTimerId );
       
   650     }
       
   651     
       
   652     
       
   653 // -----------------------------------------------------------------------------
       
   654 // CMccRtpDataSource::StandBy
       
   655 // -----------------------------------------------------------------------------
       
   656 //
       
   657 TInt CMccRtpDataSource::StandBy( 
       
   658     TMccStandbyActionType aActionType, 
       
   659     TUint aPayloadType )
       
   660     {
       
   661     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandBy, action type:%d", aActionType )
       
   662     
       
   663     TRAPD( err, StandByL( aActionType, aPayloadType ) );
       
   664     if ( err != KErrNone )
       
   665         {
       
   666         TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, error=%d", err )
       
   667         }
       
   668         
       
   669     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandBy, Exit" )   
       
   670     return err;
       
   671     }
       
   672 	
       
   673 // -----------------------------------------------------------------------------
       
   674 // CMccRtpDataSource::RtpStreamId
       
   675 // -----------------------------------------------------------------------------
       
   676 //    
       
   677 TRtpId CMccRtpDataSource::RtpStreamId()
       
   678     {
       
   679     return iRtpStreamId;
       
   680     }
       
   681 
       
   682 // -----------------------------------------------------------------------------
       
   683 // CMccRtpDataSource::RegisterPayloadTypesL
       
   684 // -----------------------------------------------------------------------------
       
   685 //
       
   686 void CMccRtpDataSource::RegisterPayloadTypesL( const RArray<TUint>& aPayloadTypes )
       
   687     {
       
   688     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::RegisterPayloadTypesL" )
       
   689     
       
   690 #ifdef _DEBUG
       
   691 
       
   692     for( TInt k = 0; k < aPayloadTypes.Count(); k++ )
       
   693         {
       
   694         TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RegisterPayloadTypesL PT: %u",
       
   695             aPayloadTypes[k] )
       
   696         }
       
   697         
       
   698 #endif
       
   699     
       
   700     
       
   701     TInt ind = aPayloadTypes.Count();
       
   702     while ( ind-- )
       
   703         {
       
   704         if ( !FindUserEntryByPayloadType( aPayloadTypes[ind] ) )
       
   705             {
       
   706             TMccRtpUser entry( iEventHandler );
       
   707             entry.iPayloadType = aPayloadTypes[ind];
       
   708             iUsers.AppendL( entry );
       
   709             }
       
   710         }
       
   711     }
       
   712             
       
   713 // -----------------------------------------------------------------------------
       
   714 // CMccRtpDataSource::UnRegisterPayloadTypes
       
   715 // Unregisters payload types to accept.
       
   716 // -----------------------------------------------------------------------------
       
   717 //
       
   718 void CMccRtpDataSource::UnRegisterPayloadTypes( const RArray<TUint>& aPayloadTypes )
       
   719     {
       
   720 #ifdef _DEBUG
       
   721 
       
   722     for( TInt k = 0; k < aPayloadTypes.Count(); k++ )
       
   723         {
       
   724         TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::UnRegisterPayloadTypes PT: %u",
       
   725             aPayloadTypes[k] )
       
   726         }
       
   727         
       
   728 #endif
       
   729 
       
   730     TInt ind = aPayloadTypes.Count();
       
   731     while ( ind-- )
       
   732         {
       
   733         TMccRtpUser* userEntry = FindUserEntryByPayloadType( aPayloadTypes[ind] );
       
   734         TInt index = FindUserEntryIndex( userEntry );
       
   735         if ( index != KErrNotFound )
       
   736             {
       
   737             iUsers.Remove( index );
       
   738             }
       
   739         }
       
   740     }
       
   741 
       
   742 // -----------------------------------------------------------------------------
       
   743 // CMccRtpDataSource::ValidatePacketL
       
   744 // Validates the received RTP packet and it's header
       
   745 // -----------------------------------------------------------------------------
       
   746 //
       
   747 TMccRtpUser* CMccRtpDataSource::ValidatePacketL( const TRtpId aStreamId, 
       
   748         const TRtpRecvHeader& aHeader, const TDesC8& aData )
       
   749     {
       
   750     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL" )
       
   751     
       
   752     __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) );
       
   753     __ASSERT_ALWAYS( iBufferToFill->Data().MaxSize() >= aData.Size(),
       
   754         User::Leave( KErrOverflow ) );
       
   755     
       
   756     TMccRtpUser* userEntry = FindUserEntryByPayloadType( aHeader.iPayloadType );
       
   757     TBool isCN = EFalse;
       
   758     
       
   759     if ( KCnPayloadType == aHeader.iPayloadType ||
       
   760          KCnPayloadTypeReserved == aHeader.iPayloadType )
       
   761         {
       
   762         isCN = ETrue;
       
   763         }
       
   764     
       
   765     if ( !userEntry )
       
   766         {
       
   767         if ( iCurRecvPayloadType != aHeader.iPayloadType && !isCN )
       
   768             {
       
   769             TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL Unknown media" )
       
   770             
       
   771             iCurRecvPayloadType = aHeader.iPayloadType;
       
   772             
       
   773             // Support for unsymmetric speech codecs, payload type is reported as
       
   774             // an error code in this case.
       
   775             SendStreamEventToClient( KMccUnknownMediaReceived,
       
   776                 aHeader.iPayloadType );
       
   777             }         
       
   778         
       
   779         if ( !isCN )
       
   780             {
       
   781             TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL PT NOK" )
       
   782             
       
   783             User::Leave( KErrNotSupported );
       
   784             }
       
   785         
       
   786         // Try to find user on current PT so the inactivity could be reset.
       
   787         userEntry = FindUserEntryByPayloadType( iCurRecvPayloadType );
       
   788         }
       
   789     else if ( userEntry &&
       
   790               KMaxTUint == userEntry->iTimerId &&
       
   791               isCN )
       
   792         {
       
   793         // This is because timers are used against the main payloadtype in CN
       
   794         // cases.
       
   795         userEntry = FindUserEntryByPayloadType( iCurRecvPayloadType );
       
   796         }
       
   797     
       
   798     if ( iRtpAPI && ( iRtpStreamId != aStreamId ) )
       
   799         {
       
   800         // Adapt to SSRC change
       
   801         iRtpAPI->CloseStream( iRtpStreamId );
       
   802         iRtpStreamId = aStreamId;
       
   803         }
       
   804     
       
   805     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::ValidatePacketL userEntry: 0x%x",
       
   806         userEntry )
       
   807     
       
   808     return userEntry;
       
   809     }
       
   810     
       
   811 // -----------------------------------------------------------------------------
       
   812 // CMccRtpDataSource::SendStreamEventToClient()
       
   813 // -----------------------------------------------------------------------------
       
   814 //	
       
   815 void CMccRtpDataSource::SendStreamEventToClient( 
       
   816     TMccEventType aEventType,
       
   817     TInt aError,
       
   818     TUint32 aTargetPayloadType )
       
   819     {
       
   820     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendStreamEventToClient" )
       
   821     
       
   822     if ( iEventHandler )
       
   823 	    {
       
   824 	    ClearMccEvent();
       
   825 	    
       
   826 	    iMccEvent.iEndpointId = MCC_RTPSOURCE_ENDPOINT_ID;
       
   827 	    iMccEvent.iEventCategory = KMccEventCategoryStream;
       
   828 	    iMccEvent.iEventType = aEventType;
       
   829 	    iMccEvent.iErrorCode = aError;
       
   830 	    
       
   831 	    if ( aTargetPayloadType != KMccPTNotDefined )
       
   832 	        {
       
   833     	    iMccEvent.iEventNumData = KMccPayloadSpecificEvent;
       
   834     	    iMccEvent.iReserved = aTargetPayloadType;
       
   835 	        }
       
   836 
       
   837 		TMccInternalEvent internalEvent( KMccRtpSourceUid, 
       
   838 		                                 EMccInternalEventNone,
       
   839 		                                 iMccEvent );
       
   840 		                         
       
   841 		iEventHandler->SendEventToClient( internalEvent );
       
   842 	    }
       
   843 	else
       
   844 		{
       
   845 		TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendStreamEventToClient, \
       
   846 		iEventHandler=NULL" )
       
   847 		}
       
   848     }
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 // CMccRtpDataSource::SendJitterEvent()
       
   852 // -----------------------------------------------------------------------------
       
   853 //	
       
   854 void CMccRtpDataSource::SendJitterEvent( TMccRtpEventData aEvent, TInt aError )
       
   855     {
       
   856     TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendJitterEvent" )
       
   857 	    
       
   858 	SendInternalRtpEventToClient( iEventHandler,
       
   859 	                              KMccRtpSourceUid, 
       
   860                                   EMccInternalJitterEventStatusReport, 
       
   861                                   KMccMediaQualityStatus,
       
   862                                   MCC_RTPSOURCE_ENDPOINT_ID,
       
   863                                   aError,
       
   864                                   aEvent.iJitterEstimate,
       
   865                                   aEvent.iPacketsReceived,
       
   866                                   aEvent.iPrevTransTime,
       
   867                                   aEvent.iTriggeredJitterLevel );
       
   868     }  
       
   869 
       
   870 // -----------------------------------------------------------------------------
       
   871 // CMccRtpDataSource::SourceCustomCommand()
       
   872 // 
       
   873 // -----------------------------------------------------------------------------
       
   874 //
       
   875 void CMccRtpDataSource::SourceCustomCommand( TMMFMessage& aMessage )
       
   876     {
       
   877     TRAPD( err, SourceCustomCommandL( aMessage ) );
       
   878     
       
   879     #ifdef TRACE_RTP_SOURCE
       
   880         RDebug::Print( _L("CMcpRtpDataSource::SourceCustomCommand ERR: %d"), err );
       
   881     #endif
       
   882     
       
   883     aMessage.Complete( err );
       
   884     }
       
   885 
       
   886 // -----------------------------------------------------------------------------
       
   887 // CMccRtpDataSource::SourceCustomCommandL()
       
   888 // Worker function for TRAP'ping possible leaves that custom commands may have
       
   889 // -----------------------------------------------------------------------------
       
   890 //    
       
   891 void CMccRtpDataSource::SourceCustomCommandL( TMMFMessage& aMessage )
       
   892     {
       
   893     #ifdef TRACE_RTP_SOURCE
       
   894         RDebug::Print( _L("CMcpRtpDataSource::SourceCustomCommandL FUNC: %d"), aMessage.Function() );
       
   895     #endif
       
   896     
       
   897     switch( aMessage.Function() )
       
   898         {
       
   899         case EStartMediaQualityObserving:
       
   900             // Send message data to jitter calculator, SetMediaConfigsL will
       
   901             // leave with KErrAlreadyExists if there is already a pending
       
   902             // client request, which will propagate to SourceCustomCommand()
       
   903             iJitCalc->SetMediaConfigsL( aMessage );
       
   904             User::LeaveIfError( iJitCalc->StartObserving() );
       
   905             break;
       
   906             
       
   907         case ECancelMediaQualityObserving:
       
   908             if ( iJitCalc->IsObserving() )
       
   909                 {
       
   910                 iJitCalc->CancelObserving();               
       
   911                 }
       
   912             else
       
   913                 {             
       
   914                 User::Leave( KErrNotReady );
       
   915                 }
       
   916             break;
       
   917 
       
   918         default:
       
   919             // Not supported CustomCommand => Leave 
       
   920             User::Leave( KErrNotSupported );
       
   921             break;
       
   922         }
       
   923     }
       
   924 
       
   925 // -----------------------------------------------------------------------------
       
   926 // CMccRtpDataSource::InactivityTimerActive
       
   927 // -----------------------------------------------------------------------------
       
   928 //
       
   929 TBool CMccRtpDataSource::InactivityTimerActive() const
       
   930     {
       
   931     return ( iInactivityTimerId != KMaxTUint32 && 
       
   932              iTimer && 
       
   933              iTimer->IsRunning( iInactivityTimerId ) );
       
   934     }
       
   935 
       
   936 // -----------------------------------------------------------------------------
       
   937 // CMccRtpDataSource::StandbyEnabled
       
   938 // -----------------------------------------------------------------------------
       
   939 //   
       
   940 TBool CMccRtpDataSource::StandbyEnabled( TMccRtpUser* aUser ) const
       
   941     {
       
   942     return ( iCodecInfo.iType == KUidMediaTypeAudio && 
       
   943              iStandByTimerValue > 0 &&
       
   944              aUser &&
       
   945              aUser->iStandbyState != ETurnedOff );
       
   946     }
       
   947     	
       
   948 // -----------------------------------------------------------------------------
       
   949 // CMccRtpDataSource::StandByL
       
   950 // -----------------------------------------------------------------------------
       
   951 //
       
   952 void CMccRtpDataSource::StandByL( 
       
   953     TMccStandbyActionType aActionType, 
       
   954     TUint aPayloadType )
       
   955     {
       
   956     TMccRtpUser* userEntry = FindUserEntryByPayloadType( aPayloadType );
       
   957     __ASSERT_ALWAYS( userEntry, User::Leave( KErrNotFound ) );
       
   958     
       
   959     switch ( aActionType )
       
   960         {
       
   961         case EForceStandby:
       
   962             {
       
   963             if ( ERtpStatePlaying == State() )
       
   964                 {
       
   965                 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandByL, force" )
       
   966                 iTimer->Stop( userEntry->iTimerId );
       
   967                 HandleStandByL( userEntry );
       
   968                 }
       
   969             break;
       
   970             }
       
   971         case EActivateStandby:
       
   972             {
       
   973             TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, activate, \
       
   974 standby state before: %d", userEntry->iStandbyState )
       
   975 
       
   976             if ( userEntry->iStandbyState == EActivating )
       
   977                 {
       
   978                 // If currently activating, activation was not possible,
       
   979                 // stop timer and wait that mechanism is activated again
       
   980                 iTimer->Stop( userEntry->iTimerId );
       
   981                 }
       
   982             else if ( userEntry->iStandbyState == EActive )
       
   983                 {
       
   984                 // If was active, re-activation can
       
   985                 // be tried when data for this user is received.
       
   986                 iTimer->Stop( userEntry->iTimerId );
       
   987                 userEntry->iStandbyState = EInactive;
       
   988                 }
       
   989             else 
       
   990                 {
       
   991                 // NOP
       
   992                 }
       
   993                 
       
   994             TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, activate, \
       
   995 standby state after: %d", userEntry->iStandbyState )
       
   996 
       
   997             break;
       
   998             }
       
   999         case EDeactivateStandby:
       
  1000             {
       
  1001             TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandByL, deactivate" )
       
  1002             iTimer->Stop( userEntry->iTimerId );
       
  1003             userEntry->iStandbyState = ETurnedOff;
       
  1004             break;
       
  1005             }
       
  1006         default:
       
  1007             {
       
  1008             User::Leave( KErrArgument );
       
  1009             break;
       
  1010             }
       
  1011         }
       
  1012     }
       
  1013 
       
  1014 // -----------------------------------------------------------------------------
       
  1015 // CMccRtpDataSource::StartRtpStandByTimerL
       
  1016 // Starts rtp standby timer 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 //
       
  1019 void CMccRtpDataSource::StartRtpStandByTimerL( TMccRtpUser* aUser )
       
  1020 	{
       
  1021     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iStartedOnce: %d",
       
  1022         aUser->iStartedOnce )
       
  1023     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iPayloadType: %d",
       
  1024         aUser->iPayloadType )
       
  1025     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iTimerId: %d",
       
  1026         aUser->iTimerId )
       
  1027     TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iStandbyState: %d",
       
  1028         aUser->iStandbyState )
       
  1029     
       
  1030     if ( StandbyEnabled( aUser ) ) 
       
  1031         {
       
  1032         // It does not matter whether timer is active or not
       
  1033         iTimer->Stop( aUser->iTimerId );
       
  1034         aUser->iTimerId = iTimer->StartL( this, iStandByTimerValue );
       
  1035         
       
  1036         TRACE_RTP_SOURCE_PRINT ( "CMCCRtpDataSource::StartRtpStandByTimer standby enabled" )
       
  1037         }
       
  1038 	}
       
  1039 	
       
  1040 // -----------------------------------------------------------------------------
       
  1041 // CMccRtpDataSource::StopRtpStandByTimers
       
  1042 // Stop rtp standby timers
       
  1043 // -----------------------------------------------------------------------------
       
  1044 //
       
  1045 void CMccRtpDataSource::StopRtpStandByTimers()
       
  1046 	{
       
  1047 	TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StopRtpStandByTimer" )
       
  1048 	
       
  1049 	// Stop all rtp standby timers
       
  1050 	for ( TInt i = 0; i < iUsers.Count(); i++ )
       
  1051 	    {
       
  1052 	    iTimer->Stop( iUsers[ i ].iTimerId );
       
  1053 	    }
       
  1054 	}
       
  1055 
       
  1056 // -----------------------------------------------------------------------------
       
  1057 // CMccRtpDataSource::ResetStandBy
       
  1058 // -----------------------------------------------------------------------------
       
  1059 //
       
  1060 void CMccRtpDataSource::ResetStandBy()
       
  1061 	{
       
  1062 	TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::ResetStandBy" )
       
  1063 	
       
  1064 	// Stop all rtp standby timers
       
  1065 	for ( TInt i = 0; i < iUsers.Count(); i++ )
       
  1066 	    {
       
  1067 	    iUsers[ i ].iStandbyState = EInactive;
       
  1068 	    }
       
  1069 	}
       
  1070 	
       
  1071 // -----------------------------------------------------------------------------
       
  1072 // CMccRtpDataSource::HandleStandByL
       
  1073 // -----------------------------------------------------------------------------
       
  1074 //	
       
  1075 void CMccRtpDataSource::HandleStandByL( TMccRtpUser* aUser )    
       
  1076 	{
       
  1077 	__ASSERT_ALWAYS( StandbyEnabled( aUser ), User::Leave( KErrNotSupported ) );
       
  1078 
       
  1079      TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::HandleStandByL, deactivate, \
       
  1080 standby state before: %d", aUser->iStandbyState )
       
  1081 
       
  1082     aUser->iStandbyState = EDeactivating;
       
  1083     
       
  1084     SendStreamEventToClient( KMccStandbyInactivityEvent, 
       
  1085        	                     KErrNone, 
       
  1086        	                     aUser->iPayloadType );
       
  1087 	
       
  1088 	aUser->iStandbyState = EInactive;
       
  1089 	
       
  1090      TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::HandleStandByL, deactivate, \
       
  1091 standby state after: %d", aUser->iStandbyState )
       
  1092 	}
       
  1093 
       
  1094 // ---------------------------------------------------------------------------
       
  1095 // CMccRtpDataSource::DoStandByDecision
       
  1096 // If standby activation has been done for some other payload type than
       
  1097 // currently received payload type, stream for old payload type is paused
       
  1098 // and stream for the new payload type is started/resumed.
       
  1099 // ---------------------------------------------------------------------------
       
  1100 //    
       
  1101 void CMccRtpDataSource::DoStandByDecision( TMccRtpUser* aUser )
       
  1102     {
       
  1103 
       
  1104 
       
  1105     if ( StandbyEnabled( aUser ) && 
       
  1106        ( aUser->iStandbyState == EInactive || aUser->iStandbyState == EDeactivating ) )
       
  1107         {
       
  1108         TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoStandByDecision, \
       
  1109 standby state before: %d", aUser->iStandbyState )
       
  1110 
       
  1111         aUser->iStandbyState = EActivating;
       
  1112         
       
  1113         SendStreamEventToClient( KMccStandbyActivityEvent, 
       
  1114 	  	                         KErrNone, 
       
  1115 	  	                         iCurRecvPayloadType );
       
  1116 	  	
       
  1117 	  	if ( aUser->iStandbyState == EActivating )
       
  1118 	  	    {
       
  1119             aUser->iStandbyState = EActive;
       
  1120 	  	    }
       
  1121 	  	    
       
  1122         TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoStandByDecision, \
       
  1123 standby state after: %d", aUser->iStandbyState )
       
  1124         }
       
  1125     }
       
  1126 		
       
  1127 // ---------------------------------------------------------------------------
       
  1128 // CMccRtpDataSource::FindUserEntryByPayloadType
       
  1129 // ---------------------------------------------------------------------------
       
  1130 //
       
  1131 TMccRtpUser* CMccRtpDataSource::FindUserEntryByPayloadType( TUint aPayloadType )
       
  1132     {
       
  1133     TMccRtpUser entry( iEventHandler );
       
  1134     entry.iPayloadType = aPayloadType;
       
  1135     TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch );
       
  1136     const TInt index = iUsers.Find( entry, comparison );
       
  1137     if ( index != KErrNotFound )
       
  1138         {
       
  1139         return &iUsers[ index ];
       
  1140         }
       
  1141     
       
  1142     return NULL;
       
  1143     }
       
  1144 
       
  1145 // ---------------------------------------------------------------------------
       
  1146 // CMccRtpDataSource::FindRtpUserEntryByTimerId
       
  1147 // ---------------------------------------------------------------------------
       
  1148 //
       
  1149 TMccRtpUser* CMccRtpDataSource::FindUserEntryByTimerId( TMccTimerId aTimerId )
       
  1150     {
       
  1151     TMccRtpUser entry( iEventHandler );
       
  1152     entry.iTimerId = aTimerId;
       
  1153     TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch );
       
  1154     TInt index = iUsers.Find( entry, comparison );
       
  1155     if ( index != KErrNotFound )
       
  1156         {
       
  1157         return &iUsers[ index ];
       
  1158         }
       
  1159     return NULL;
       
  1160     }
       
  1161     
       
  1162 // ---------------------------------------------------------------------------
       
  1163 // CMccRtpDataSource::FindUserEntryIndex
       
  1164 // ---------------------------------------------------------------------------
       
  1165 //
       
  1166 TInt CMccRtpDataSource::FindUserEntryIndex( TMccRtpUser* aUser )
       
  1167     {
       
  1168     TInt index( KErrNotFound );
       
  1169     if ( aUser )
       
  1170         {
       
  1171         TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch );
       
  1172         index = iUsers.Find( *aUser, comparison );
       
  1173         }
       
  1174     return index;
       
  1175     }
       
  1176         
       
  1177 // ---------------------------------------------------------------------------
       
  1178 // CMccRtpDataSource::RtpUserMatch
       
  1179 // ---------------------------------------------------------------------------
       
  1180 //   
       
  1181 TBool CMccRtpDataSource::RtpUserMatch( 
       
  1182     const TMccRtpUser& aUser1, 
       
  1183     const TMccRtpUser& aUser2 )
       
  1184     {
       
  1185     // First argument is always the search term
       
  1186     
       
  1187     TBool match( EFalse );
       
  1188     if ( aUser1.iPayloadType != KMccPTNotDefined )
       
  1189         {
       
  1190         match = ( aUser1.iPayloadType == aUser2.iPayloadType );
       
  1191         }
       
  1192     else if ( aUser1.iTimerId != KMaxTUint32 )
       
  1193         {
       
  1194         match = ( aUser1.iTimerId == aUser2.iTimerId );
       
  1195         }
       
  1196     else
       
  1197         {
       
  1198         match = ( &aUser1 == &aUser2 );
       
  1199         }
       
  1200     return match;
       
  1201     }
       
  1202         
       
  1203 // ---------------------------------------------------------------------------
       
  1204 // FROM SRTP API
       
  1205 // This function is called by SRTP Stream initiated with 
       
  1206 // MSRTPReKeyingObserver when a master key is stale and needs 
       
  1207 // to be refreshed.  
       
  1208 // ---------------------------------------------------------------------------
       
  1209 //
       
  1210 void CMccRtpDataSource::SRTPMasterKeyStaleEvent( const CSRTPStream& aStream )
       
  1211     {
       
  1212     TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSource::SRTPMasterKeyStaleEvent" )
       
  1213     
       
  1214     if ( iSrtpStream == &aStream )
       
  1215         {                                    
       
  1216         iSecureKeyExpired = ETrue;
       
  1217         SendSecureRtpEventToClient( iEventHandler,
       
  1218                                     KMccRtpSourceUid,
       
  1219                                     EMccInternalEventNone,
       
  1220                                     KMccMasterKeyStaled,
       
  1221                                     MCC_RTPSOURCE_ENDPOINT_ID );
       
  1222         }
       
  1223     else
       
  1224         {
       
  1225         TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSource::SRTPMasterKeyStaleEvent - Wrong stream" )
       
  1226         }
       
  1227     }
       
  1228 
       
  1229 // ---------------------------------------------------------------------------
       
  1230 // FROM SRTP API
       
  1231 // This function is called by SRTP Stream initiated with 
       
  1232 // CSRTPSession  when a master key is stale and
       
  1233 // needs to be refreshed.  
       
  1234 // ---------------------------------------------------------------------------
       
  1235 //
       
  1236 void CMccRtpDataSource::SRTPMasterKeyStaleEvent(const CSRTPSession& aSession )
       
  1237     {
       
  1238     TRACE_RTP_INTERFACE_PRINT( "CMccRtpStream::SRTPMasterKeyStaleEvent" )
       
  1239     
       
  1240     if ( iSecSession == &aSession )
       
  1241         {
       
  1242         iSecureKeyExpired = ETrue;
       
  1243         SendSecureRtpEventToClient( iEventHandler,
       
  1244                                     KMccRtpSourceUid,
       
  1245                                     EMccInternalEventNone,
       
  1246                                     KMccMasterKeyStaled,
       
  1247                                     MCC_RTPSOURCE_ENDPOINT_ID );
       
  1248 
       
  1249         }
       
  1250     else
       
  1251         {
       
  1252         TRACE_RTP_INTERFACE_PRINT( "MccRtpStream::SRTPMasterKeyStaleEvent - Wrong session" )
       
  1253         }
       
  1254     } 
       
  1255 
       
  1256 // -----------------------------------------------------------------------------
       
  1257 // CMccRtpDataSource::TimerExpiredL
       
  1258 // From MMccExpirationHandler
       
  1259 // -----------------------------------------------------------------------------
       
  1260 //
       
  1261 void CMccRtpDataSource::TimerExpiredL( TMccTimerId aTimerId, TAny* /*aTimerParam*/ )
       
  1262     {
       
  1263     TRACE_RTP_SOURCE_PRINT2( "CMccRtpStream::TimerExpiredL, timer id: %d", aTimerId )
       
  1264     if ( aTimerId == iInactivityTimerId )
       
  1265         {
       
  1266         TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::TimerExpiredL, inactivity timer expired" )
       
  1267     
       
  1268         SendInternalRtpEventToClient( iEventHandler,
       
  1269                                       KMccRtpSourceUid, 
       
  1270                                       KMccInternalRtpSrcMmfEvent, 
       
  1271                                       KMccInactivityEvent,
       
  1272                                       MCC_RTPSOURCE_ENDPOINT_ID );
       
  1273         }
       
  1274     else
       
  1275         {
       
  1276         // Standby timeout
       
  1277         TMccRtpUser* userEntry = FindUserEntryByTimerId( aTimerId );
       
  1278         HandleStandByL( userEntry );
       
  1279         }
       
  1280     }
       
  1281     
       
  1282 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1283 
       
  1284 //  End of File