mmsharing/mmshengine/src/musengmcesession.cpp
changeset 15 ccd8e69b5392
parent 2 b31261fd4e04
child 20 e8be2c2e049d
child 22 496ad160a278
equal deleted inserted replaced
2:b31261fd4e04 15:ccd8e69b5392
     1 /*
       
     2 * Copyright (c) 2005 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 // USER
       
    20 #include "mussettings.h"
       
    21 #include "musengmcesession.h"
       
    22 #include "musengsessiondurationtimer.h"
       
    23 #include "musengsessionobserver.h"
       
    24 #include "musengmceutils.h"
       
    25 #include "musuid.hrh"
       
    26 #include "musenglogger.h"
       
    27 #include "musengclipsessionobserver.h"
       
    28 #include "mussipprofilehandler.h"
       
    29 
       
    30 // SYSTEM
       
    31 #include <mcedefs.h>
       
    32 #include <mcemanager.h>
       
    33 #include <mceinsession.h>
       
    34 #include <mcevideostream.h>
       
    35 #include <mceaudiostream.h>
       
    36 #include <mcertpsink.h>
       
    37 #include <mcedisplaysink.h>
       
    38 #include <mcespeakersink.h>
       
    39 #include <mcefilesource.h>
       
    40 #include <mcertpsource.h>
       
    41 #include <mceaudiocodec.h>
       
    42 #include <mcevideocodec.h>
       
    43 #include <AudioPreference.h>
       
    44 
       
    45 
       
    46 const TInt KMusEngTimerInterval = 1000000; // 1 second
       
    47 const TInt KMusEngRtcpInactivityThreshold = 20; // seconds
       
    48 const TInt KMusEngArrayGranularity3 = 3;
       
    49 
       
    50 const TInt KMusEngSipReasonCodeOk = 200;
       
    51 const TInt KMusEngSipReasonCodeBusyHere = 486;
       
    52 _LIT8( KMusEngSipReasonPhraseBusyHere, "Busy Here" );
       
    53 _LIT8( KMusEngSipReasonPhraseBusy, "Busy" );
       
    54 
       
    55 const TUint KMusEngDedicatedVideoPort = 49152;
       
    56 const TUint KMusEngDedicatedAudioPort = 57344;
       
    57 
       
    58 #define MUS_CODEC_ARR_CONST_CAST( codecArr ) \
       
    59 ( const_cast< RPointerArray< CMceVideoCodec >& >( codecArr ) )
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 CMusEngMceSession::~CMusEngMceSession()
       
    66     {
       
    67     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::~CMusEngMceSession()" )
       
    68     delete iSipProfileHandler;
       
    69     delete iSession;
       
    70     delete iManager;
       
    71     delete iUpdateTimer;
       
    72     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::~CMusEngMceSession()" )
       
    73     }
       
    74 
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 EXPORT_C void CMusEngMceSession::TerminateL()
       
    81     {
       
    82     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::TerminateL()" )
       
    83     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
    84     iSession->TerminateL();
       
    85     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::TerminateL()" )
       
    86     }
       
    87 
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // Returns estabilished session time. If not established return
       
    91 // value is < 0
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 EXPORT_C TTimeIntervalSeconds CMusEngMceSession::GetSessionTime() const
       
    95     {
       
    96     if ( iSession && iSession->State() == CMceSession::EEstablished )
       
    97         {
       
    98         TTime time;
       
    99         TTimeIntervalSeconds seconds;
       
   100         time.HomeTime();
       
   101 
       
   102         time.SecondsFrom( iStartTime, seconds );
       
   103 
       
   104         return seconds;
       
   105         }
       
   106 
       
   107     return TTimeIntervalSeconds( KErrNotReady );
       
   108 
       
   109     }
       
   110 
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 // -----------------------------------------------------------------------------
       
   115 //
       
   116 EXPORT_C TBool CMusEngMceSession::ConnectionActive() const
       
   117     {
       
   118     if ( iSession )
       
   119         {
       
   120         return iSession->ConnectionActive();
       
   121         }
       
   122     return EFalse;
       
   123     }
       
   124 
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 EXPORT_C TBool CMusEngMceSession::ContainsAudioL()
       
   131     {
       
   132     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   133                                             
       
   134     for ( TInt i = 0; i < iSession->Streams().Count(); ++i )
       
   135         {
       
   136         if ( iSession->Streams()[i]->Type() == KMceAudio )
       
   137             {
       
   138             return ETrue;
       
   139             }
       
   140         }
       
   141 
       
   142     return EFalse;
       
   143     }
       
   144        
       
   145         
       
   146 // -----------------------------------------------------------------------------
       
   147 // 
       
   148 // -----------------------------------------------------------------------------
       
   149 //
       
   150 EXPORT_C TBool CMusEngMceSession::IsMutedL()
       
   151     {
       
   152     // Precondition checked in ContainsAudioL
       
   153     
       
   154     if ( ContainsAudioL() && !iExplicitlyMuted )
       
   155         {
       
   156         return EFalse;
       
   157         }
       
   158     
       
   159     return ETrue;
       
   160     }
       
   161 
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 EXPORT_C CMusEngMceSession::TDisplayOrientation 
       
   168                                             CMusEngMceSession::OrientationL()
       
   169     {
       
   170     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::RotationL()" )
       
   171     
       
   172     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   173     
       
   174     CMceDisplaySink* display = MusEngMceUtils::GetDisplayL( *iSession );
       
   175     
       
   176     TDisplayOrientation displayOrientation;
       
   177     CMceDisplaySink::TRotation rotation( display->RotationL() );
       
   178     
       
   179     MUS_LOG1( "mus: [ENGINE]     MCE rotation is %d", rotation )
       
   180     
       
   181     if ( rotation == CMceDisplaySink::ENone )
       
   182         {
       
   183         displayOrientation = CMusEngMceSession::EPortrait;
       
   184         }
       
   185     else
       
   186         {
       
   187         displayOrientation = CMusEngMceSession::ELandscape;
       
   188         }
       
   189     
       
   190     MUS_LOG1( "mus: [ENGINE]  <- CMusEngMceSession::RotationL() %d", 
       
   191               displayOrientation )
       
   192     
       
   193     return displayOrientation;
       
   194     }
       
   195 
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 // -----------------------------------------------------------------------------
       
   200 //        
       
   201 EXPORT_C void CMusEngMceSession::SetOrientationL( 
       
   202                                         TDisplayOrientation aOrientation )
       
   203     {
       
   204     MUS_LOG1( "mus: [ENGINE]  -> CMusEngMceSession::SetOrientationL() %d", 
       
   205               aOrientation )
       
   206               
       
   207     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   208     
       
   209     CMceDisplaySink* display = MusEngMceUtils::GetDisplayL( *iSession );
       
   210 
       
   211     if ( aOrientation == EPortrait )
       
   212         {
       
   213         display->SetRotationL( CMceDisplaySink::ENone );
       
   214         }
       
   215     else
       
   216         {
       
   217         display->SetRotationL( CMceDisplaySink::EClockwise90Degree );
       
   218         }
       
   219 
       
   220     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::SetOrientationL()" )
       
   221     }
       
   222 
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C void CMusEngMceSession::VolumeUpL()
       
   229     {
       
   230     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   231 
       
   232     CMusEngSession::VolumeUpL();
       
   233 
       
   234     SetSpeakerVolumeL( VolumeL() );
       
   235     }
       
   236 
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 EXPORT_C void CMusEngMceSession::VolumeDownL()
       
   243     {
       
   244     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   245 
       
   246     CMusEngSession::VolumeDownL();
       
   247 
       
   248     SetSpeakerVolumeL( VolumeL() );
       
   249     }
       
   250 
       
   251 
       
   252 // -----------------------------------------------------------------------------
       
   253 // 
       
   254 // 
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 EXPORT_C void CMusEngMceSession::SetVolumeL( TInt aVal )
       
   258     {
       
   259     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   260 
       
   261     CMusEngSession::SetVolumeL( aVal );
       
   262 
       
   263     SetSpeakerVolumeL( VolumeL() );
       
   264     }
       
   265 
       
   266 
       
   267 // -----------------------------------------------------------------------------
       
   268 // 
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 EXPORT_C void CMusEngMceSession::EnableDisplayL( TBool aEnable )
       
   272     {
       
   273     MUS_LOG1( "mus: [ENGINE]     -> CMusEngMceSession::EnableDisplay() %d", 
       
   274               aEnable )
       
   275 
       
   276     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   277 
       
   278     CMceDisplaySink* display = MusEngMceUtils::GetDisplayL( *iSession );
       
   279     
       
   280     if ( aEnable )
       
   281         {
       
   282         if ( !display->IsEnabled() )
       
   283             {
       
   284             display->EnableL();
       
   285             MUS_LOG( "                  Display enabled" )
       
   286             if ( !iExplicitlyMuted )
       
   287                 {
       
   288                 // Since speaker is not explicitly muted, but disabled as
       
   289                 // a consequence of disabling bundled display, it must be
       
   290                 // unmuted.
       
   291                 DoMuteSpeakerL( EFalse );
       
   292                 MUS_LOG( "                  Bundled speaker enabled" )
       
   293                 }
       
   294             }
       
   295         else
       
   296             {
       
   297             MUS_LOG( "                  Display already enabled, ignore" )
       
   298             }
       
   299         }
       
   300     else
       
   301         {
       
   302         if ( display->IsEnabled() )
       
   303             {
       
   304             display->DisableL();
       
   305             MUS_LOG( "                  Display disabled" )
       
   306             if ( !iExplicitlyMuted )
       
   307                 {
       
   308                 // Speaker will not be explicitly muted, but disabled as
       
   309                 // a consequence of disabling bundled display.
       
   310                 DoMuteSpeakerL( ETrue );
       
   311                 MUS_LOG( "                  Bundled speaker disabled" )
       
   312                 }
       
   313             }
       
   314         else
       
   315             {
       
   316             MUS_LOG( "                  Display already disabled, ignore" )
       
   317             }
       
   318         }
       
   319       
       
   320         
       
   321     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::EnableDisplay()")
       
   322     }
       
   323 
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // Mutes playback of sended audio streams. Audio data is still streamed.
       
   327 // -----------------------------------------------------------------------------
       
   328 //
       
   329 EXPORT_C void CMusEngMceSession::MuteL()
       
   330     {
       
   331     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::Mute()" )
       
   332 
       
   333     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   334 
       
   335     DoMuteSpeakerL( ETrue );
       
   336     
       
   337     // Mark speaker as explicitly muted instead of muted because of disabling
       
   338     // bundled display
       
   339     iExplicitlyMuted = ETrue; 
       
   340 
       
   341     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::Mute()" )
       
   342     }
       
   343 
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // Unmutes playback of sended audio streams.
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 EXPORT_C void CMusEngMceSession::UnmuteL()
       
   350     {
       
   351     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::Unmute()" )
       
   352 
       
   353     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   354 
       
   355     DoMuteSpeakerL( EFalse );
       
   356 
       
   357     // Mark speaker as explicitly unmuted instead of unmuted because of 
       
   358     // enabling bundled display
       
   359     iExplicitlyMuted = EFalse;
       
   360 
       
   361     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::Unmute()" )
       
   362     }
       
   363 
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 //
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 CMusEngMceSession::CMusEngMceSession( const TRect& aRect,
       
   370                                       MMusEngSessionObserver& aSessionObserver )
       
   371     : CMusEngSession( aRect ),
       
   372       iSessionObserver( aSessionObserver ),
       
   373       iSecondsFromLastRtcpReport ( 0 ),
       
   374       // Although speaker is constructed as muted, it is not explicitly muted
       
   375       iExplicitlyMuted( EFalse ) 
       
   376     {
       
   377     }
       
   378 
       
   379 
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 // -----------------------------------------------------------------------------
       
   383 //
       
   384 void CMusEngMceSession::ConstructL()
       
   385     {
       
   386     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::ConstructL()" )
       
   387     CMusEngSession::ConstructL(); // Base class ConstructL -first
       
   388 
       
   389     // Creating new MCE Manager and set all needed observers to this class.
       
   390     iManager = CMceManager::NewL( TUid::Uid( KMusUiUid ),
       
   391                                   &iTransactionDataContainer );
       
   392 
       
   393     iManager->SetSessionObserver( this );
       
   394     iManager->SetInSessionObserver( this );
       
   395     iManager->SetMediaObserver( this );
       
   396     iManager->SetRtpObserver( this );
       
   397 
       
   398     // Check if operator specific behavior is expected
       
   399     iOperatorVariant = ( MultimediaSharingSettings::OperatorVariantSettingL() ==
       
   400                          MusSettingsKeys::EOperatorSpecific );
       
   401     
       
   402     // Update timer initialization
       
   403     iUpdateTimer = CMusEngSessionDurationTimer::NewL( *this );
       
   404     	
       
   405   	iSipProfileHandler = CMusSipProfileHandler::NewL( *this );
       
   406 
       
   407     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::ConstructL()" )
       
   408     }
       
   409 
       
   410 
       
   411 // -----------------------------------------------------------------------------
       
   412 //
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 void CMusEngMceSession::RectChangedL()
       
   416     {
       
   417     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::RectChangedL()" )
       
   418 
       
   419     // If session is not yet created, do nothing
       
   420     if ( iSession && iSession->State() != CMceSession::ETerminated )
       
   421         {
       
   422         // Rely on having just one display
       
   423         CMceDisplaySink* display = MusEngMceUtils::GetDisplayL( *iSession );
       
   424         display->SetDisplayRectL( Rect() );
       
   425         }
       
   426 
       
   427     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::RectChangedL()" )
       
   428     }
       
   429 
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // Setting session level sdp lines. Bandwith attribute is always used in
       
   433 // operator variant mode and at receiver side (using force). 
       
   434 // However, bandwidth attribute is preferred to be used at media level
       
   435 // (see SetMediaSdpLinesL method). It is set to session level only if other
       
   436 // side is using also session level bandwidth. Media level preference exists
       
   437 // because some other manufacturer's videosharing does not understand session
       
   438 // level bandwidth attribute.
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 void CMusEngMceSession::SetSessionSdpLinesL( 
       
   442     CMceSession& aSession, 
       
   443     TBool aForceBandwidthLine )
       
   444     {
       
   445     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::SetSessionSdpLinesL()" )
       
   446     
       
   447     MDesC8Array* oldSessionSdpLines = aSession.SessionSDPLinesL();
       
   448     CleanupDeletePushL( oldSessionSdpLines );
       
   449     TBool bandwidthAtSessionLevel( ContainsText( oldSessionSdpLines, 
       
   450                                    KMusEngSessionSdpLineBandwidthLine() ) );
       
   451     CleanupStack::PopAndDestroy( oldSessionSdpLines );
       
   452     
       
   453     CDesC8Array* newSessionSDPLines = 
       
   454                     new ( ELeave ) CDesC8ArrayFlat( KMusEngArrayGranularity3 );
       
   455     CleanupStack::PushL( newSessionSDPLines );
       
   456     
       
   457     if ( iOperatorVariant )
       
   458         {
       
   459         newSessionSDPLines->AppendL( KMusEngSessionSdpLineApplication() );
       
   460         newSessionSDPLines->AppendL( KMusEngSessionSdpLineType() );
       
   461         }
       
   462     else
       
   463     	{
       
   464     	newSessionSDPLines->AppendL( KMusEngSessionSdpLineXApplication() );	
       
   465     	}
       
   466     
       
   467     if ( bandwidthAtSessionLevel && ( iOperatorVariant || aForceBandwidthLine ) )
       
   468 	    {
       
   469 	    MUS_LOG( "mus: [ENGINE] setting bandwidth to session level" )
       
   470         newSessionSDPLines->AppendL( KMusEngSessionSdpLineBandwidthField() );
       
   471 	    }
       
   472     	        
       
   473     aSession.SetSessionSDPLinesL( newSessionSDPLines );
       
   474     
       
   475     CleanupStack::Pop( newSessionSDPLines );
       
   476     
       
   477     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::SetSessionSdpLinesL()" )
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // Setting media level sdp lines. Bandwidth is not set to media level if
       
   482 // it is used already at session level.
       
   483 // -----------------------------------------------------------------------------
       
   484 //
       
   485 void CMusEngMceSession::SetMediaSdpLinesL( 
       
   486     CMceMediaStream& aStream, 
       
   487     TBool aForceBandwidthLine )
       
   488     {
       
   489     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::SetMediaSdpLinesL()" )
       
   490     
       
   491     MDesC8Array* sessionSdpLines = aStream.Session()->SessionSDPLinesL();
       
   492     CleanupDeletePushL( sessionSdpLines );
       
   493     TBool bandwidthAtSessionLevel( ContainsText( sessionSdpLines, 
       
   494                                    KMusEngSessionSdpLineBandwidthLine() ) );
       
   495     CleanupStack::PopAndDestroy( sessionSdpLines );
       
   496     
       
   497     if ( !bandwidthAtSessionLevel && ( iOperatorVariant || aForceBandwidthLine ) )
       
   498         {
       
   499     	MUS_LOG( "mus: [ENGINE] setting bandwidth to media level" )
       
   500 		
       
   501 		//Add media attribute to sdp
       
   502 		const TInt KMusMediaSdpLinesGranularity = 1;
       
   503 		CDesC8Array* headers = 
       
   504 		    new ( ELeave ) CDesC8ArrayFlat( KMusMediaSdpLinesGranularity );
       
   505 		CleanupStack::PushL( headers );
       
   506 		headers->AppendL( KMusEngSessionSdpLineBandwidthField() );
       
   507 		aStream.SetMediaAttributeLinesL( headers );   
       
   508 		CleanupStack::Pop( headers );
       
   509         }
       
   510 		
       
   511     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::SetMediaSdpLinesL()" )
       
   512     }
       
   513     
       
   514 // -----------------------------------------------------------------------------
       
   515 // Changes volume of all speaker sinks in the session structure
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 void CMusEngMceSession::SetSpeakerVolumeL( TInt aNewVolume )
       
   519     {
       
   520     TInt sessionState = iSession->State();
       
   521 
       
   522     if ( sessionState != CMceSession::EIdle &&
       
   523          sessionState != CMceSession::EIncoming )
       
   524         {
       
   525         for ( TInt i = 0; i < iSession->Streams().Count(); ++i )
       
   526             {
       
   527             CMceSpeakerSink* speaker = 
       
   528                 MusEngMceUtils::GetSpeaker( *( iSession->Streams()[i] ) );
       
   529 
       
   530             if ( speaker &&        
       
   531                  aNewVolume >= 1 &&
       
   532                  aNewVolume <= KMusEngMaxVolume )
       
   533                 {
       
   534                 // MCE might have different scale for volume than MUS
       
   535                 // so adjust MUS volume to MCE scale before setting.
       
   536                 TInt maxVol = speaker->MaxVolumeL();
       
   537                 TInt setVol = maxVol * aNewVolume / KMusEngMaxVolume;
       
   538                 setVol = Max(setVol, 1);
       
   539                 
       
   540                 MUS_LOG2(
       
   541 "mus: [ENGINE]  -> CMusEngMceSession::SetSpeakerVolumeL() orig:%d, adjusted:%d", 
       
   542 aNewVolume, setVol );
       
   543                 
       
   544                 if ( setVol <= maxVol )
       
   545                     {
       
   546                     speaker->SetVolumeL( setVol );
       
   547                     }
       
   548                 }
       
   549             }
       
   550         }
       
   551     }
       
   552 
       
   553 
       
   554 // -----------------------------------------------------------------------------
       
   555 //
       
   556 // -----------------------------------------------------------------------------
       
   557 //   
       
   558 void CMusEngMceSession::AdjustStreamsAndCodecsL()
       
   559     {
       
   560     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::AdjustStreamsAndCodecsL" )
       
   561 
       
   562     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   563 
       
   564     const RPointerArray<CMceMediaStream>& streams = iSession->Streams();
       
   565 
       
   566     for ( TInt i = 0; i < streams.Count(); ++i )
       
   567         {
       
   568         if ( streams[i]->Type() == KMceVideo )
       
   569             {
       
   570             CMceVideoStream* videoStream =
       
   571                                     static_cast<CMceVideoStream*>( streams[i] );
       
   572             
       
   573             AdjustVideoStreamL( *videoStream );
       
   574             
       
   575             if ( videoStream->BoundStream() )
       
   576                 {
       
   577                 AdjustVideoStreamL( static_cast<CMceVideoStream&>
       
   578                                         ( videoStream->BoundStreamL() ) );
       
   579                 }
       
   580             
       
   581             }
       
   582         else // audio
       
   583             {
       
   584             CMceAudioStream* audioStream = 
       
   585                                     static_cast<CMceAudioStream*>( streams[i] );
       
   586             
       
   587             AdjustAudioStreamL( *audioStream );
       
   588             
       
   589             if ( audioStream->BoundStream() )
       
   590                 {
       
   591                 AdjustAudioStreamL( static_cast<CMceAudioStream&>
       
   592                                         ( audioStream->BoundStreamL() ) );
       
   593                 }
       
   594         
       
   595             }
       
   596         }
       
   597     
       
   598     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::AdjustStreamsAndCodecsL" )
       
   599     
       
   600     }
       
   601 
       
   602 
       
   603 // -----------------------------------------------------------------------------
       
   604 //
       
   605 // -----------------------------------------------------------------------------
       
   606 //  
       
   607 void CMusEngMceSession::AdjustVideoStreamL( CMceVideoStream& aVideoStream )
       
   608     {
       
   609     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::AdjustVideoStreamL" )
       
   610     
       
   611     aVideoStream.SetLocalMediaPortL( KMusEngDedicatedVideoPort );
       
   612     
       
   613     DoCodecSelectionL( aVideoStream );
       
   614     
       
   615     const RPointerArray<CMceVideoCodec>& codecs = aVideoStream.Codecs();
       
   616         
       
   617     for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
       
   618         {
       
   619         AdjustVideoCodecL( *codecs[codecIndex] );
       
   620         }
       
   621     
       
   622     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::AdjustVideoStreamL" )
       
   623     }
       
   624 
       
   625 
       
   626 // -----------------------------------------------------------------------------
       
   627 //
       
   628 // -----------------------------------------------------------------------------
       
   629 //  
       
   630 void CMusEngMceSession::AdjustAudioStreamL( CMceAudioStream& aAudioStream )
       
   631     {
       
   632     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::AdjustAudioStreamL" )
       
   633     
       
   634     aAudioStream.SetLocalMediaPortL( KMusEngDedicatedAudioPort );
       
   635 
       
   636     const RPointerArray<CMceAudioCodec> codecs = aAudioStream.Codecs();
       
   637     
       
   638     for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
       
   639         {
       
   640         AdjustAudioCodecL( *codecs[codecIndex] );
       
   641         }
       
   642     
       
   643     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::AdjustAudioStreamL" )
       
   644     }
       
   645     
       
   646 
       
   647 // -----------------------------------------------------------------------------
       
   648 // Calls CMceInSession::RejectL() inside TRAP_IGNORE
       
   649 // -----------------------------------------------------------------------------
       
   650 //
       
   651 void CMusEngMceSession::Reject( CMceInSession& aSession,
       
   652                                 const TDesC8& aReason,
       
   653                                 TUint32 aCode )
       
   654     {
       
   655     if ( aCode != 0 || aReason != KNullDesC8() )
       
   656         {
       
   657         TRAP_IGNORE( aSession.RejectL( aReason, aCode, NULL, NULL, NULL ) )
       
   658         }
       
   659     else
       
   660         {
       
   661         if ( iOperatorVariant )
       
   662             {
       
   663             // In operator variant, session is rejected with 486 instead of 603.
       
   664             // Also the reason phrase is supposed to be "Busy".
       
   665             TRAP_IGNORE( aSession.RejectL( KMusEngSipReasonPhraseBusy(), 
       
   666                                            KMusEngSipReasonCodeBusyHere ) )
       
   667             }
       
   668         else
       
   669             {
       
   670             // Normal case
       
   671             TRAP_IGNORE( aSession.RejectL() )
       
   672             }
       
   673         }
       
   674     }
       
   675     
       
   676 
       
   677 // -----------------------------------------------------------------------------
       
   678 // By default rejects all incoming sessions immediately without notifying UI
       
   679 // -----------------------------------------------------------------------------
       
   680 //
       
   681 void CMusEngMceSession::IncomingSession( 
       
   682                       CMceInSession* aSession,
       
   683                       TMceTransactionDataContainer* /*aContainer*/ )
       
   684     {
       
   685     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::IncomingSession()" )
       
   686     
       
   687     Reject( *aSession, 
       
   688             KMusEngSipReasonPhraseBusyHere(),
       
   689             KMusEngSipReasonCodeBusyHere );
       
   690              
       
   691     delete aSession;
       
   692     aSession = NULL;    
       
   693     
       
   694     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::IncomingSession()" )
       
   695     }
       
   696 
       
   697 
       
   698 // -----------------------------------------------------------------------------
       
   699 // By default rejects all incoming updates immediately without notifying UI
       
   700 // -----------------------------------------------------------------------------
       
   701 //
       
   702 void CMusEngMceSession::IncomingUpdate( 
       
   703                      CMceSession& aOrigSession, 
       
   704                      CMceInSession* aUpdatedSession,
       
   705                      TMceTransactionDataContainer* /*aContainer*/ )
       
   706     {
       
   707     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::IncomingUpdate()" )
       
   708                                     
       
   709     if ( iSession &&
       
   710          iSession == &aOrigSession )
       
   711         {
       
   712         // Old session is useless from now on
       
   713         delete iSession;
       
   714         iSession = aUpdatedSession;
       
   715         MUS_LOG( "mus: [ENGINE]  Unexpected update, reject" )
       
   716         Reject( *aUpdatedSession );    
       
   717         }
       
   718     else
       
   719         {
       
   720         // This should never happen
       
   721         MUS_LOG( "mus: [ENGINE]  Unknown update, reject and delete" )
       
   722         Reject( *aUpdatedSession );    
       
   723         delete aUpdatedSession;
       
   724         } 
       
   725     
       
   726     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::IncomingUpdate()" )    
       
   727     }
       
   728     
       
   729 
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 // -----------------------------------------------------------------------------
       
   733 //
       
   734 void CMusEngMceSession::StreamStateChanged( CMceMediaStream& aStream )
       
   735     {
       
   736     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::StreamStateChanged()" )
       
   737     
       
   738     if ( !iSession )
       
   739         {
       
   740         return; // We cannot do anything
       
   741         }
       
   742     
       
   743     MUS_ENG_LOG_STREAM_STATE( aStream )
       
   744         
       
   745     switch ( aStream.State() )
       
   746         {
       
   747         case CMceMediaStream::EUninitialized: // Stream is created
       
   748             {
       
   749             // Unexpected state change
       
   750             break;
       
   751             }
       
   752         case CMceMediaStream::EInitialized: // Stream is initialized
       
   753             {
       
   754             // Should be handled in sibling classes if needed
       
   755             break;
       
   756             }
       
   757         case CMceMediaStream::EBuffering: // Stream is buffering
       
   758             {
       
   759             // Should be handled in sibling classes if needed
       
   760             break;
       
   761             }
       
   762         case CMceMediaStream::EIdle: // Stream is not receiving RTP
       
   763             {
       
   764             // NOP
       
   765             break;
       
   766             }
       
   767         case CMceMediaStream::EStreaming: // Stream is streaming
       
   768             {
       
   769             // If streaming stream is complete video out- or instream, inform UI 
       
   770             if ( aStream.Type() == KMceVideo &&
       
   771                  aStream.Source() && 
       
   772                  aStream.Sinks().Count() >= 0 &&
       
   773                  ( aStream.Source()->Type() == KMceRTPSource ||
       
   774                    aStream.Sinks()[0]->Type() == KMceRTPSink ) )
       
   775                 {
       
   776                 iSessionObserver.StreamStreaming();
       
   777                 }
       
   778             break;
       
   779             }
       
   780         case CMceMediaStream::EDisabled: // Stream is explicitly disabled
       
   781             {
       
   782             break;
       
   783             }
       
   784         case CMceMediaStream::ENoResources: 
       
   785             {
       
   786             // Stream has no needed resources to stream
       
   787             break;
       
   788             }         
       
   789         case CMceMediaStream::ETranscodingRequired: 
       
   790             {
       
   791             // Stream requires non-realtime transcoding
       
   792             // Should be handled in sibling classes
       
   793             break;
       
   794             }   
       
   795         case CMceMediaStream::ETranscoding: 
       
   796             {
       
   797             // Stream is transcoding in non-realtime
       
   798             // Should be handled in sibling classes
       
   799             break;
       
   800             }       
       
   801         default:
       
   802             {
       
   803             break;
       
   804             }
       
   805         }
       
   806     
       
   807     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::StreamStateChanged()" )
       
   808                 
       
   809     }
       
   810 
       
   811 
       
   812 // -----------------------------------------------------------------------------
       
   813 //
       
   814 // -----------------------------------------------------------------------------
       
   815 //
       
   816 void CMusEngMceSession::StreamStateChanged( CMceMediaStream& aStream,
       
   817                                             CMceMediaSource& /*aSource*/ )
       
   818     {
       
   819     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::StreamStateChanged( src )" )
       
   820     // Use default logic
       
   821     StreamStateChanged( aStream );
       
   822     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::StreamStateChanged( src )" )       
       
   823     }
       
   824 
       
   825 
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 // -----------------------------------------------------------------------------
       
   829 //
       
   830 void CMusEngMceSession::StreamStateChanged( CMceMediaStream& aStream,
       
   831                                             CMceMediaSink& /*aSink*/ )
       
   832     {
       
   833     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::StreamStateChanged( sink )" )
       
   834     // Use default logic
       
   835     StreamStateChanged( aStream );
       
   836     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::StreamStateChanged( sink )" )
       
   837     }
       
   838 
       
   839 
       
   840 // -----------------------------------------------------------------------------
       
   841 //
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 void CMusEngMceSession::SessionStateChanged(
       
   845                         CMceSession& aSession,
       
   846                         TMceTransactionDataContainer* aContainer )
       
   847     {
       
   848     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::SessionStateChanged()" )
       
   849         
       
   850     if ( !aContainer )
       
   851         {
       
   852         // Container should never be NULL, but if it is, handle as
       
   853         // internal error
       
   854         iSessionObserver.SessionFailed();
       
   855         return;
       
   856         }
       
   857 
       
   858     // This is the only point to get statuscode and reasonphrase. With this call
       
   859     // they are zeroed and thus cannot be got anymore.
       
   860     TInt statusCode = aContainer->GetStatusCode();
       
   861     HBufC8* reasonPhrase = aContainer->GetReasonPhrase();
       
   862     
       
   863     if ( reasonPhrase )
       
   864         {        
       
   865         HandleSessionStateChanged( aSession, statusCode, *reasonPhrase ); 
       
   866         delete reasonPhrase ;       
       
   867         }
       
   868     else
       
   869         {
       
   870         HandleSessionStateChanged( aSession, statusCode, KNullDesC8() );
       
   871         }
       
   872     
       
   873     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::SessionStateChanged()" )
       
   874     }
       
   875             
       
   876     
       
   877 // -----------------------------------------------------------------------------
       
   878 //
       
   879 // -----------------------------------------------------------------------------
       
   880 //
       
   881 void CMusEngMceSession::SessionConnectionStateChanged( CMceSession& aSession,
       
   882                                                        TBool aActive )
       
   883     {
       
   884     MUS_LOG1( "mus: [ENGINE]     CMusEngMceSession::\
       
   885               SessionConnectionStateChanged() active = %b", aActive )
       
   886 
       
   887     if ( iSession && iSession == &aSession )
       
   888         {
       
   889         if ( !aActive )
       
   890             {
       
   891             MUS_LOG( "mus: [ENGINE]     CMusEngMceSession::\
       
   892                      SessionConnectionStateChanged: Notify observer" )
       
   893             iSessionObserver.SessionConnectionLost();
       
   894             }
       
   895         }
       
   896 
       
   897     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::\
       
   898              SessionConnectionStateChanged()" )
       
   899     }
       
   900 
       
   901 
       
   902 // -----------------------------------------------------------------------------
       
   903 //
       
   904 // -----------------------------------------------------------------------------
       
   905 //
       
   906 
       
   907 #if ( defined( _DEBUG ) && !defined( UNIT_TESTING ) ) 
       
   908 void CMusEngMceSession::Failed( CMceSession& aSession, TInt aError )
       
   909 #else
       
   910 void CMusEngMceSession::Failed( CMceSession& aSession, TInt /*aError*/ )
       
   911 #endif
       
   912     {
       
   913     MUS_LOG1( "mus: [ENGINE]     -> CMusEngMceSession::Failed() error #%d", 
       
   914               aError )
       
   915     
       
   916     if ( iSession && iSession == &aSession )
       
   917         {
       
   918         MUS_LOG( "mus: [ENGINE]    CMusEngMceSession::Failed: Notify observer" )
       
   919         iSessionObserver.SessionFailed();
       
   920         }
       
   921 
       
   922     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::Failed()" )
       
   923     }
       
   924 
       
   925 
       
   926 // -----------------------------------------------------------------------------
       
   927 //
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 void CMusEngMceSession::UpdateFailed(
       
   931                    CMceSession& aSession,
       
   932                    TMceTransactionDataContainer* aContainer )
       
   933     {
       
   934     MUS_LOG( "mus: [ENGINE] -> CMusEngMceSession::UpdateFailed()" )
       
   935 
       
   936     if ( !aContainer )
       
   937         {
       
   938         // Container should never be NULL, but if it is, handle as
       
   939         // internal error
       
   940         iSessionObserver.SessionFailed();
       
   941         return;
       
   942         }
       
   943 
       
   944     if ( iSession && iSession == &aSession )
       
   945         {
       
   946         MUS_LOG( "mus: [ENGINE]     CMusEngMceSession::UpdateFailed: \
       
   947                  Notify observer" )
       
   948         iSessionObserver.SessionFailed();
       
   949         }
       
   950 
       
   951     MUS_LOG( "mus: [ENGINE] <- CMusEngMceSession::UpdateFailed()" )
       
   952     }
       
   953 
       
   954 
       
   955 // -----------------------------------------------------------------------------
       
   956 //
       
   957 // -----------------------------------------------------------------------------
       
   958 //
       
   959 void CMusEngMceSession::SRReceived( CMceSession& aSession,
       
   960 					                CMceMediaStream& aStream)
       
   961     {
       
   962     // No logging because of amount of reports
       
   963     if ( iSession &&
       
   964          iSession == &aSession )
       
   965         {
       
   966         for ( TInt i = 0; i < iSession->Streams().Count(); ++i )
       
   967             {
       
   968             if ( &aStream == iSession->Streams()[i] )
       
   969                 {
       
   970                 iSecondsFromLastRtcpReport = 0;
       
   971                 }
       
   972             }
       
   973         }
       
   974     }
       
   975 
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 // -----------------------------------------------------------------------------
       
   979 //
       
   980 void CMusEngMceSession::RRReceived( CMceSession& aSession,
       
   981 					                CMceMediaStream& aStream)
       
   982     {
       
   983     // No logging because of amount of reports
       
   984 
       
   985     if ( iSession &&
       
   986          iSession == &aSession )
       
   987         {
       
   988         for ( TInt i = 0; i < iSession->Streams().Count(); ++i )
       
   989             {
       
   990             if ( &aStream == iSession->Streams()[i] )
       
   991                 {
       
   992                 iSecondsFromLastRtcpReport = 0;
       
   993                 }
       
   994             }
       
   995         }
       
   996     }	             
       
   997 					             
       
   998 
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 // -----------------------------------------------------------------------------
       
  1002 //
       
  1003 void CMusEngMceSession::InactivityTimeout( CMceMediaStream& aStream,
       
  1004                                            CMceRtpSource& /*aSource*/ )
       
  1005     {
       
  1006     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::InactivityTimeout()" )
       
  1007     // This function may be deprecated in future and after that similar 
       
  1008     // functionality can be obtained by observing stream state EIdle.
       
  1009     // Anyway it does not work yet and until then, informing UI about 
       
  1010     // RTP inactivity is done in this function.
       
  1011     
       
  1012     if ( aStream.Type() == KMceVideo )
       
  1013         {
       
  1014         iSessionObserver.StreamIdle();
       
  1015         }
       
  1016     
       
  1017     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::InactivityTimeout()" )
       
  1018     }
       
  1019 
       
  1020 
       
  1021 // -----------------------------------------------------------------------------
       
  1022 //
       
  1023 // -----------------------------------------------------------------------------
       
  1024 //
       
  1025 void CMusEngMceSession::SsrcAdded( CMceMediaStream& /*aStream*/,
       
  1026                                    CMceRtpSource& /*aSource*/,
       
  1027                                    TUint /*aSsrc*/ )
       
  1028     {
       
  1029     MUS_LOG( "mus: [ENGINE]  CMusEngMceSession::SsrcAdded( ... )" )
       
  1030     // NOP, We are not at all interested about SSRCs
       
  1031     }
       
  1032 
       
  1033 
       
  1034 // -----------------------------------------------------------------------------
       
  1035 //
       
  1036 // -----------------------------------------------------------------------------
       
  1037 //
       
  1038 void CMusEngMceSession::SsrcRemoved( CMceMediaStream& /*aStream*/,
       
  1039                                      CMceRtpSource& /*aSource*/,
       
  1040                                      TUint /*aSsrc*/ )
       
  1041     {
       
  1042     MUS_LOG( "mus: [ENGINE]  CMusEngMceSession::SsrcRemoved(... )" )
       
  1043     // NOP, We are not at all interested about SSRCs
       
  1044     }
       
  1045 
       
  1046 
       
  1047 // -----------------------------------------------------------------------------
       
  1048 //
       
  1049 // -----------------------------------------------------------------------------
       
  1050 //
       
  1051 TBool CMusEngMceSession::IsRoamingBetweenAPsAllowed()
       
  1052     {
       
  1053     TBool allowed( ETrue );
       
  1054     if ( iSession && 
       
  1055          iSession->State() != CMceSession::EIdle &&
       
  1056          iSession->State() != CMceSession::ETerminated )
       
  1057         {
       
  1058         allowed = EFalse;
       
  1059         }
       
  1060     return allowed;
       
  1061     }
       
  1062 
       
  1063 
       
  1064 // -----------------------------------------------------------------------------
       
  1065 //
       
  1066 // -----------------------------------------------------------------------------
       
  1067 //
       
  1068 void CMusEngMceSession::HandleSessionStateChanged( CMceSession& aSession,
       
  1069                                                    TInt aStatusCode,
       
  1070                                                    const TDesC8& aReasonPhrase )
       
  1071     {
       
  1072     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::HandleSessionStateChanged" )
       
  1073     
       
  1074     MUS_ENG_LOG_SESSION_STATE_AND_STATUS( aSession, aStatusCode, aReasonPhrase ) 
       
  1075 
       
  1076     if ( iSession && iSession == &aSession )
       
  1077         {
       
  1078         switch ( aSession.State() )
       
  1079             {
       
  1080             case CMceSession::EIdle:
       
  1081                 {
       
  1082                 MUS_LOG( "mus: [ENGINE] Unexpected asynchronous \
       
  1083                          state transition, consider session as failed." )
       
  1084                 iSessionObserver.SessionFailed();
       
  1085                 break;
       
  1086                 }
       
  1087             case CMceSession::EOffering :
       
  1088                 {
       
  1089                 break;
       
  1090                 }
       
  1091             case CMceSession::EIncoming:
       
  1092                 {
       
  1093                 MUS_LOG( "mus: [ENGINE] Unexpected asynchronous \
       
  1094                          state transition, consider session as failed." )
       
  1095                 iSessionObserver.SessionFailed();
       
  1096                 break;
       
  1097                 }
       
  1098             case CMceSession::EReserving :
       
  1099                 {
       
  1100                 // UpdateL called to incoming session during
       
  1101                 // session establishment
       
  1102                 break;
       
  1103                 }
       
  1104             case CMceSession::EAnswering :  // Answering an incoming call
       
  1105                 {
       
  1106                 break;
       
  1107                 }
       
  1108             case CMceSession::EProceeding :
       
  1109                 {
       
  1110                 break;
       
  1111                 }
       
  1112             case CMceSession::EEstablished:
       
  1113                 {
       
  1114                 // Check that session timer is not already running, which is 
       
  1115                 // the case when refreshing the session with session timer 
       
  1116                 if ( !iUpdateTimer->IsActive() )
       
  1117                     {
       
  1118                     iStartTime.HomeTime(); // Start counting session duration              
       
  1119                     iUpdateTimer->Start( KMusEngTimerInterval );
       
  1120                     iSessionObserver.SessionEstablished();
       
  1121                     }
       
  1122                     
       
  1123                 break;
       
  1124                 }
       
  1125             case CMceSession::ECancelling:
       
  1126                 {
       
  1127                 // MCE has for some reason started to cancel session
       
  1128                 break;
       
  1129                 }
       
  1130             case CMceSession::ETerminating:
       
  1131                 {
       
  1132                 // MCE has for some reason started to terminate session
       
  1133                 break;
       
  1134                 }
       
  1135             case CMceSession::ETerminated:
       
  1136                 {
       
  1137                 HandleTermination( aStatusCode, aReasonPhrase );
       
  1138                 break;
       
  1139                 }
       
  1140             default:
       
  1141                 {
       
  1142                 MUS_LOG( "mus: [ENGINE]  CMusEngMceSession::SessionStateChanged(), \
       
  1143                          default case" )
       
  1144                 break;
       
  1145                 }
       
  1146             }
       
  1147         }
       
  1148         
       
  1149     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::HandleSessionStateChanged" )
       
  1150     }
       
  1151 
       
  1152 
       
  1153 // -----------------------------------------------------------------------------
       
  1154 // This function should be called only if sibling classes cannot handle
       
  1155 // termination reason by themselves.
       
  1156 // -----------------------------------------------------------------------------
       
  1157 //
       
  1158 void CMusEngMceSession::HandleTermination( TInt aStatusCode,
       
  1159                                            const TDesC8& /*aReasonPhrase*/ )
       
  1160     {
       
  1161     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::HandleTermination()" )
       
  1162 
       
  1163 	iSipProfileHandler->RefreshIapAvailabilities();
       
  1164 
       
  1165     switch ( aStatusCode )
       
  1166         {
       
  1167         case 0:
       
  1168             {
       
  1169             // Normal session termination or session by another end.
       
  1170             iSessionObserver.SessionTerminated();
       
  1171             break;
       
  1172             }
       
  1173         case KMusEngSipReasonCodeOk:
       
  1174             {
       
  1175             // Normal session termination by this end: We have sent BYE
       
  1176             // and now received 200 OK to it.
       
  1177             iSessionObserver.SessionTerminated();
       
  1178             break;
       
  1179             }
       
  1180         default:
       
  1181             {
       
  1182             // Termination reason cannot be determined, handle as internal
       
  1183             // error.
       
  1184             iSessionObserver.SessionFailed();
       
  1185             break;
       
  1186             }
       
  1187         }
       
  1188 
       
  1189     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::HandleTermination()" )
       
  1190     }
       
  1191 
       
  1192 
       
  1193 // -----------------------------------------------------------------------------
       
  1194 //
       
  1195 // -----------------------------------------------------------------------------
       
  1196 //
       
  1197 void CMusEngMceSession::AdjustVideoCodecL( CMceVideoCodec& aVideoCodec )
       
  1198     {
       
  1199     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::AdjustVideoCodecL()" )
       
  1200     
       
  1201     aVideoCodec.SetMMFPriorityL( KAudioPrioritySwisPlayback );
       
  1202     aVideoCodec.SetMMFPriorityPreferenceL( KAudioPrefSwisPlayback );
       
  1203     MUS_LOG( "mus: [ENGINE]     Video MMF priority and preference set" )
       
  1204 
       
  1205     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::AdjustVideoCodecL()" )
       
  1206     }
       
  1207 
       
  1208  
       
  1209 // -----------------------------------------------------------------------------
       
  1210 // 1. Sets MMF audio priority and preference
       
  1211 // -----------------------------------------------------------------------------
       
  1212 //
       
  1213 void CMusEngMceSession::AdjustAudioCodecL( CMceAudioCodec& aAudioCodec )
       
  1214     {
       
  1215     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::AdjustAudioCodecL()" )
       
  1216     
       
  1217     aAudioCodec.SetMMFPriorityL( KAudioPrioritySwisPlayback );
       
  1218     aAudioCodec.SetMMFPriorityPreferenceL( KAudioPrefSwisPlayback );
       
  1219     MUS_LOG( "mus: [ENGINE]     Audio MMF priority and preference set" )
       
  1220     
       
  1221     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::AdjustAudioCodecL()" )
       
  1222     }
       
  1223 
       
  1224 
       
  1225 // -----------------------------------------------------------------------------
       
  1226 // Remove multiples of H.263 codec, prefer H263-2000 over H263-1998.
       
  1227 // Additionally select just the one with best quality from selected mode.
       
  1228 // -----------------------------------------------------------------------------
       
  1229 //
       
  1230 void CMusEngMceSession::DoCodecSelectionL( CMceVideoStream& aVideoStream )
       
  1231     {
       
  1232     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::DoCodecSelectionL()" )
       
  1233     
       
  1234     const RPointerArray<CMceVideoCodec>& codecs = aVideoStream.Codecs();
       
  1235     TBool codecModeBasedRemovalNeeded( EFalse );
       
  1236     // Label:H263
       
  1237     TBool H2632000CodecFound( EFalse );
       
  1238     TBool H2631998CodecFound( EFalse );
       
  1239     for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
       
  1240         {
       
  1241         const CMceVideoCodec& currentCodec = *codecs[codecIndex];
       
  1242         if ( currentCodec.SdpName().FindF( KMceSDPNameH263 ) != KErrNotFound )
       
  1243             { 
       
  1244             if ( !currentCodec.SdpName().CompareF( KMceSDPNameH2632000 ) )
       
  1245                 {
       
  1246                 H2632000CodecFound = ETrue;
       
  1247                 codecModeBasedRemovalNeeded = H2631998CodecFound;
       
  1248                 }  
       
  1249             else if ( !currentCodec.SdpName().CompareF( KMceSDPNameH2631998 ) )
       
  1250                 {
       
  1251                 H2631998CodecFound = ETrue;
       
  1252                 codecModeBasedRemovalNeeded = H2632000CodecFound;
       
  1253                 }
       
  1254             else 
       
  1255                 {
       
  1256                 // NOP
       
  1257                 }
       
  1258             }
       
  1259         }
       
  1260     if ( codecModeBasedRemovalNeeded )
       
  1261         {
       
  1262         DoCodecModeBasedRemovalL( aVideoStream );
       
  1263         }
       
  1264     
       
  1265     const RPointerArray<CMceVideoCodec>& codecs2 = aVideoStream.Codecs();
       
  1266     const CMceVideoCodec* bestBitrateCodec( NULL );
       
  1267     for ( TInt codecIndex = 0; codecIndex < codecs2.Count(); ++codecIndex )
       
  1268         {
       
  1269         const CMceVideoCodec& currentCodec = *codecs2[codecIndex];
       
  1270         if ( currentCodec.SdpName().FindF( KMceSDPNameH263 ) != KErrNotFound )
       
  1271             {
       
  1272             if ( !bestBitrateCodec || 
       
  1273                  currentCodec.MaxBitRate() > bestBitrateCodec->MaxBitRate() )
       
  1274                 {
       
  1275                 bestBitrateCodec = &currentCodec;
       
  1276                 } 
       
  1277             }
       
  1278         }        
       
  1279     if ( bestBitrateCodec != NULL )
       
  1280         {
       
  1281         DoBitrateBasedRemovalL( aVideoStream, *bestBitrateCodec );
       
  1282         }
       
  1283    
       
  1284     /* Codec removal based on configuration */
       
  1285     DoCodecConfigurationBasedRemovalL( aVideoStream );
       
  1286     
       
  1287     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::DoCodecSelectionL()" )
       
  1288     }
       
  1289     
       
  1290 
       
  1291 // -----------------------------------------------------------------------------
       
  1292 //
       
  1293 // -----------------------------------------------------------------------------
       
  1294 //
       
  1295 void CMusEngMceSession::UpdateTimerEvent()
       
  1296     {
       
  1297     // Update timer is used also to detect RTCP inactivity
       
  1298     ++iSecondsFromLastRtcpReport;
       
  1299     
       
  1300     iSessionObserver.SessionTimeChanged( GetSessionTime() );
       
  1301 
       
  1302     if ( iSecondsFromLastRtcpReport >= KMusEngRtcpInactivityThreshold )
       
  1303         {
       
  1304         iSessionObserver.InactivityTimeout();    
       
  1305         // Disable calling multiple times by reseting timer
       
  1306         iSecondsFromLastRtcpReport = 0;
       
  1307         }
       
  1308 
       
  1309     iUpdateTimer->Start( KMusEngTimerInterval );
       
  1310     }
       
  1311 
       
  1312 
       
  1313 // -----------------------------------------------------------------------------
       
  1314 // Enables or disables all the speaker sinks of all the audio streams
       
  1315 // -----------------------------------------------------------------------------
       
  1316 //
       
  1317 void CMusEngMceSession::DoMuteSpeakerL( TBool aMute )
       
  1318     {
       
  1319     MUS_LOG1( "mus: [ENGINE]     -> CMusEngMceSession::MuteL( %d )", aMute )
       
  1320     
       
  1321     const RPointerArray<CMceMediaStream>& streams = iSession->Streams();
       
  1322 
       
  1323     for ( TInt i = 0; i < streams.Count(); ++i )
       
  1324         {
       
  1325         CMceSpeakerSink* speaker = 
       
  1326                 MusEngMceUtils::GetSpeaker( *streams[i] );
       
  1327             
       
  1328         if ( speaker )
       
  1329             {
       
  1330             if( aMute )
       
  1331                 {
       
  1332                 if ( speaker->IsEnabled() )
       
  1333                     {
       
  1334                     speaker->DisableL();
       
  1335                     }
       
  1336                 else
       
  1337                     {
       
  1338                     MUS_LOG( "mus: [ENGINE]     Speaker already muted, NOP" )
       
  1339                     }
       
  1340                 }
       
  1341             else
       
  1342                 {
       
  1343                 if ( !speaker->IsEnabled() )
       
  1344                     {
       
  1345                     speaker->EnableL();
       
  1346                     }
       
  1347                 else
       
  1348                     {
       
  1349                     MUS_LOG( "mus: [ENGINE]     Speaker already unmuted, NOP" )
       
  1350                     }
       
  1351                 }
       
  1352             }
       
  1353         }
       
  1354         
       
  1355     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::MuteL( TBool aMute )" )
       
  1356     }
       
  1357 
       
  1358 // -----------------------------------------------------------------------------
       
  1359 // Checks if some of array items contains specific text 
       
  1360 // (exact match not required)
       
  1361 // -----------------------------------------------------------------------------
       
  1362 //
       
  1363 TBool CMusEngMceSession::ContainsText( MDesC8Array* aArray, const TDesC8& aItem )
       
  1364     {
       
  1365     for ( TInt i = 0; aArray && i < aArray->MdcaCount(); i++ )
       
  1366         {
       
  1367         if ( aArray->MdcaPoint( i ).FindF( aItem ) != KErrNotFound )
       
  1368             {
       
  1369             return ETrue;
       
  1370             }
       
  1371         }
       
  1372     return EFalse;
       
  1373     }
       
  1374     
       
  1375 
       
  1376 // -----------------------------------------------------------------------------
       
  1377 // 
       
  1378 // -----------------------------------------------------------------------------
       
  1379 //
       
  1380 void CMusEngMceSession::DoBitrateBasedRemovalL( 
       
  1381     CMceVideoStream& aVideoStream, 
       
  1382     const CMceVideoCodec& aBestBitrateVideoCodec )
       
  1383     {   
       
  1384     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::DoBitrateBasedRemovalL()" )
       
  1385     
       
  1386     RPointerArray<CMceVideoCodec>& codecs = 
       
  1387         MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );
       
  1388                           
       
  1389     TInt codecIndex = 0;
       
  1390     while ( codecIndex < codecs.Count() )
       
  1391         {
       
  1392         CMceVideoCodec& currentCodec = *codecs[codecIndex++];
       
  1393         if ( currentCodec.SdpName().FindF( KMceSDPNameH263 ) != KErrNotFound &&
       
  1394              &currentCodec != &aBestBitrateVideoCodec )
       
  1395             {
       
  1396             MUS_LOG( "mus: [ENGINE]         removing" )
       
  1397             aVideoStream.RemoveCodecL( currentCodec );
       
  1398             codecs = MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );
       
  1399             codecIndex = 0;
       
  1400             }
       
  1401         }
       
  1402         
       
  1403     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::DoBitrateBasedRemovalL()" )
       
  1404     }
       
  1405     
       
  1406 // -----------------------------------------------------------------------------
       
  1407 // 
       
  1408 // -----------------------------------------------------------------------------
       
  1409 //
       
  1410 void CMusEngMceSession::DoCodecModeBasedRemovalL( CMceVideoStream& aVideoStream )
       
  1411     {
       
  1412     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::DoCodecModeBasedRemovalL()" )
       
  1413     
       
  1414     RPointerArray<CMceVideoCodec>& codecs = 
       
  1415         MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );
       
  1416         
       
  1417     TInt codecIndex = 0;
       
  1418     while ( codecIndex < codecs.Count() )
       
  1419         {
       
  1420         CMceVideoCodec& currentCodec = *codecs[codecIndex++];
       
  1421         if ( !currentCodec.SdpName().CompareF( KMceSDPNameH2631998 ) )
       
  1422             {
       
  1423             MUS_LOG( "mus: [ENGINE]         removing" )
       
  1424             aVideoStream.RemoveCodecL( currentCodec );
       
  1425             codecs = MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );
       
  1426             codecIndex = 0;
       
  1427             }
       
  1428         }
       
  1429         
       
  1430     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::DoCodecModeBasedRemovalL()" )
       
  1431     }
       
  1432 
       
  1433 // -----------------------------------------------------------------------------
       
  1434 // 
       
  1435 // -----------------------------------------------------------------------------
       
  1436 //
       
  1437 void CMusEngMceSession::DoCodecConfigurationBasedRemovalL( CMceVideoStream& aVideoStream )
       
  1438     {
       
  1439     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceSession::DoCodecConfigurationBasedRemovalL()" )
       
  1440     if( MultimediaSharingSettings::IsAvcDisabled())
       
  1441         {
       
  1442         RPointerArray<CMceVideoCodec>& codecs = 
       
  1443             MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );            
       
  1444         TInt codecIndex = 0;
       
  1445         while ( codecIndex < codecs.Count() )
       
  1446             {
       
  1447             CMceVideoCodec& currentCodec = *codecs[codecIndex++];            
       
  1448             if ( !currentCodec.SdpName().CompareF( KMceSDPNameH264 ) )
       
  1449                 {
       
  1450                 MUS_LOG( "mus: [ENGINE]  - Removing avc from supported codec list" )
       
  1451                 aVideoStream.RemoveCodecL( currentCodec );
       
  1452                 codecs = MUS_CODEC_ARR_CONST_CAST( aVideoStream.Codecs() );
       
  1453                 codecIndex = 0;
       
  1454                 }
       
  1455             }
       
  1456         }    
       
  1457     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceSession::DoCodecConfigurationBasedRemovalL()" )
       
  1458     }