mmsharing/mmshengine/src/musengmceoutsession.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 "musengmceoutsession.h"
       
    21 #include "musengoutsessionobserver.h"
       
    22 #include "musenglivesessionobserver.h"
       
    23 #include "mussettings.h"
       
    24 #include "musengmceutils.h"
       
    25 #include "musenguriparser.h"
       
    26 #include "musenglogger.h"
       
    27 #include "mussesseioninformationapi.h"
       
    28 #include "mussipprofilehandler.h"
       
    29 
       
    30 // SYSTEM
       
    31 #include <mcestreambundle.h>
       
    32 #include <mcemediastream.h>
       
    33 #include <mceoutsession.h>
       
    34 #include <mcevideostream.h>
       
    35 #include <mcemediasource.h>
       
    36 #include <mcefilesource.h>
       
    37 #include <mcemediasink.h>
       
    38 #include <mcertpsink.h>
       
    39 #include <mcespeakersink.h>
       
    40 #include <mcedisplaysink.h>
       
    41 #include <mcevideocodec.h>
       
    42 #include <mceaudiocodec.h>
       
    43 
       
    44 #include <sipprofile.h>
       
    45 #include <sipextensionheader.h>
       
    46 #include <sipaddress.h>
       
    47 #include <uri8.h>
       
    48 #include <e32property.h>
       
    49 
       
    50 
       
    51 
       
    52 const TInt KMusEngSipReasonCodeBadRequest = 400;
       
    53 const TInt KMusEngSipReasonCodeUnauthorized = 401;
       
    54 const TInt KMusEngSipReasonCodePaymentRequired = 402;
       
    55 const TInt KMusEngSipReasonCodeRecipientNotFound  = 404;
       
    56 const TInt KMusEngSipReasonCodeProxyAuthenticationRequired = 407;
       
    57 const TInt KMusEngSipReasonCodeRequestTimeout = 408;
       
    58 const TInt KMusEngSipReasonCodeUnsupportedMediaType = 415;
       
    59 const TInt KMusEngSipReasonCodeUnsupportedUriScheme = 416;
       
    60 const TInt KMusEngSipReasonCodeTemporarilyNotAvailable = 480;
       
    61 const TInt KMusEngSipReasonCodeBusyHere = 486;
       
    62 const TInt KMusEngSipReasonCodeRequestCancelled = 487;
       
    63 const TInt KMusEngSipReasonCodeNotAcceptableHere = 488;
       
    64 const TInt KMusEngSipReasonCodeDecline = 603;
       
    65 const TInt KMusEngSipReasonCodeNotAcceptable = 606;
       
    66 // The next code represents unofficial sip error code
       
    67 // "478 Unresolveable Destination, we were not able to process the URI (478/TM)
       
    68 const TInt KMusEngSipReasonCode478NotAbleToProcessURI = 478;
       
    69 // The next code represents unofficial sip error code
       
    70 // "479 Regretfuly, we were not able to process the URI (479/SL)
       
    71 const TInt KMusEngSipReasonCode479NotAbleToProcessURI = 479;
       
    72 
       
    73 const TUint8 KMusEngPayloadTypeVideoH263 = 96;
       
    74 const TUint8 KMusEngPayloadTypeAudio = 97;
       
    75 const TUint8 KMusEngPayloadTypeVideoAvc = 98;
       
    76 
       
    77 using namespace NMusSessionInformationApi;
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 // -----------------------------------------------------------------------------
       
    82 //
       
    83 CMusEngMceOutSession::~CMusEngMceOutSession()
       
    84     {
       
    85     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::~CMusEngMceOutSession()" )
       
    86 
       
    87     delete iRecipient;
       
    88     delete iVideoCodecList;
       
    89     
       
    90     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::~CMusEngMceOutSession()" )
       
    91     }
       
    92 
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 EXPORT_C void CMusEngMceOutSession::InviteL( const TDesC& aRecipient )
       
    99     {
       
   100     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::InviteL()")
       
   101 
       
   102     if ( iSession )
       
   103         {
       
   104         MUS_ENG_LOG_SESSION_STATE( *iSession ) 
       
   105 
       
   106         if ( iSession->State() == CMceSession::EIdle ||
       
   107              iSession->State() == CMceSession::ETerminated )
       
   108             {
       
   109             // This is the case when last invite has ended up to an error,
       
   110             // last sharing has ended normally, or construction of the session
       
   111             // stucture has not been completed. Delete old session and try to
       
   112             // continue normally.
       
   113             delete iSession;
       
   114             iSession = NULL;
       
   115             MUS_LOG( "mus: [ENGINE]     Existing session deleted")
       
   116             }
       
   117         else
       
   118             {
       
   119             // Session is already ongoing. Leave.
       
   120             User::Leave( KErrAlreadyExists );
       
   121             }
       
   122 
       
   123         }
       
   124 
       
   125     MUS_LOG_TDESC( "mus: [ENGINE]      CMusEngMceOutSession::InviteL() recipient=",
       
   126                    aRecipient )
       
   127 
       
   128     // delete possibly existing recipient
       
   129     delete iRecipient;
       
   130     iRecipient = NULL;  
       
   131     
       
   132     TMusEngUriParser parser( aRecipient ); 
       
   133     parser.ParseUriL();    
       
   134     iRecipient = parser.GetUri8L();
       
   135 
       
   136     CreateMceSessionStructureL();
       
   137 
       
   138     EstablishSessionL();
       
   139 
       
   140     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::InviteL()")
       
   141     }
       
   142 
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 // -----------------------------------------------------------------------------
       
   147 //
       
   148 EXPORT_C void CMusEngMceOutSession::CancelInviteL()
       
   149     {
       
   150     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::CancelInviteL()" )
       
   151 
       
   152     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   153     
       
   154     MUS_ENG_LOG_SESSION_STATE( *iSession ) 
       
   155 
       
   156     if( iSession->State() == CMceSession::EOffering )
       
   157         {
       
   158         MUS_LOG( "mus: [ENGINE]     CMceOutSession->CancelL()" )
       
   159         static_cast<CMceOutSession*>( iSession )->CancelL();
       
   160         }
       
   161 
       
   162     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::CancelInviteL()" )
       
   163     }
       
   164 
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 EXPORT_C void CMusEngMceOutSession::SetSupportedVideoCodecListL( 
       
   171                                                 const TDesC& aVideoCodecs )
       
   172     {
       
   173     MUS_LOG_TDESC( "mus: [ENGINE]  -> CMusEngMceOutSession::SetSupportedVideoCodecListL: ",
       
   174                    aVideoCodecs )
       
   175 
       
   176     HBufC8* newVideoCodecList = 
       
   177                     CnvUtfConverter::ConvertFromUnicodeToUtf8L( aVideoCodecs );
       
   178     delete iVideoCodecList;
       
   179     iVideoCodecList = newVideoCodecList;
       
   180 
       
   181     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::SetSupportedVideoCodecListL" )
       
   182     }
       
   183 
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // Calls MCE function EstablishL with feature tag in Accept-Contact header.
       
   187 // Adjusts stream and codec values.
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 void CMusEngMceOutSession::EstablishSessionL()
       
   191     {
       
   192     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::EstablishSessionL()" )
       
   193     
       
   194     __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) );
       
   195     
       
   196     AdjustStreamsAndCodecsL();
       
   197     
       
   198     CDesC8Array* headers = new ( ELeave ) CDesC8ArrayFlat( 1 );
       
   199     CleanupStack::PushL( headers );
       
   200     headers->AppendL( KMusEngAcceptContactHeader() );
       
   201     headers->AppendL( KMusAcceptHeader() ); 
       
   202     if ( iOperatorVariant )
       
   203         {
       
   204         CUri8* originator = iSipProfileHandler->UserFromProfileLC();
       
   205         
       
   206         CSIPExtensionHeader* header = CSIPExtensionHeader::NewLC( 
       
   207                     KMusPPreferredIdentity, originator->Uri().UriDes() );
       
   208         HBufC8* headInText = header->ToTextL();
       
   209         MUS_LOG_TDESC8( " mus: [ENGINE] P-Preferred-Identity header : ", headInText->Des() );
       
   210         CleanupStack::PopAndDestroy( header );
       
   211         CleanupStack::PopAndDestroy( originator );
       
   212         CleanupStack::PushL( headInText );
       
   213         headers->AppendL( *headInText );
       
   214         CleanupStack::PopAndDestroy( headInText );
       
   215         }
       
   216       
       
   217      /* Add the privacy header if cs call privacy setting is switched on */
       
   218     if ( iPrivate && iPrivateNumber )
       
   219         {
       
   220         AddPrivacyHeaderL( *headers );
       
   221         }
       
   222     static_cast<CMceOutSession*>( iSession )->EstablishL( 0, headers );
       
   223     CleanupStack::Pop( headers );
       
   224     
       
   225     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::EstablishSessionL()" )
       
   226     }
       
   227 
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // Handle MCE session termination. Called by MCE observer function of the
       
   231 // base class.
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 void CMusEngMceOutSession::HandleTermination( TInt aStatusCode,
       
   235                                               const TDesC8& aReasonPhrase )
       
   236     {
       
   237     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::HandleTermination()" )
       
   238 
       
   239     switch ( aStatusCode )
       
   240         {
       
   241 
       
   242         case KMusEngSipReasonCodeBadRequest :
       
   243             {
       
   244             iOutSessionObserver.SessionBadRequest();
       
   245             break;
       
   246             }
       
   247         case KMusEngSipReasonCodeUnauthorized :
       
   248             {
       
   249             iOutSessionObserver.SessionUnauthorized();
       
   250             break;
       
   251             }
       
   252         case KMusEngSipReasonCodePaymentRequired :
       
   253             {
       
   254             iOutSessionObserver.SessionPaymentRequired();
       
   255             break;
       
   256             }
       
   257         case KMusEngSipReasonCodeRecipientNotFound :
       
   258         	//lint -fallthrough
       
   259         case KMusEngSipReasonCode478NotAbleToProcessURI:
       
   260             //lint -fallthrough
       
   261         case KMusEngSipReasonCode479NotAbleToProcessURI:
       
   262             //lint -fallthrough
       
   263         case KMusEngSipReasonCodeUnsupportedUriScheme : 
       
   264             {
       
   265             iOutSessionObserver.SessionRecipientNotFound();
       
   266             break;
       
   267             }
       
   268         case KMusEngSipReasonCodeProxyAuthenticationRequired :
       
   269             {
       
   270             iOutSessionObserver.SessionProxyAuthenticationRequired();
       
   271             break;
       
   272             }
       
   273         case KMusEngSipReasonCodeRequestTimeout :
       
   274             {
       
   275             iOutSessionObserver.SessionRequestTimeOut();
       
   276             break;
       
   277             }
       
   278         case KMusEngSipReasonCodeUnsupportedMediaType :
       
   279             //lint -fallthrough
       
   280         case KMusEngSipReasonCodeNotAcceptableHere:
       
   281             //lint -fallthrough
       
   282         case KMusEngSipReasonCodeNotAcceptable:
       
   283             {
       
   284             iOutSessionObserver.SessionUnsupportedMediaType();
       
   285             break;
       
   286             }
       
   287         case KMusEngSipReasonCodeBusyHere :
       
   288             {
       
   289             // Operator variant uses 486 to rejection instead of 603
       
   290             if ( iOperatorVariant )
       
   291                 {
       
   292                 iOutSessionObserver.SessionRejected();
       
   293                 }
       
   294             else
       
   295                 {
       
   296                 iOutSessionObserver.SessionBusyHere();
       
   297                 }
       
   298             break;
       
   299             }
       
   300         case KMusEngSipReasonCodeRequestCancelled :  
       
   301             {
       
   302             iOutSessionObserver.SessionRequestCancelled();
       
   303             break;
       
   304             }
       
   305         case KMusEngSipReasonCodeDecline :
       
   306             {
       
   307             iOutSessionObserver.SessionRejected();
       
   308             break;
       
   309             }
       
   310         case KMusEngSipReasonCodeTemporarilyNotAvailable :
       
   311             {
       
   312             iOutSessionObserver.SessionTemporarilyNotAvailable();
       
   313             break;
       
   314             }
       
   315         default:
       
   316             {
       
   317             // Termination reason is not outsession specific.
       
   318             // Let the base class to handle the termination.
       
   319             CMusEngMceSession::HandleTermination( aStatusCode, aReasonPhrase );
       
   320             }
       
   321         }
       
   322 
       
   323 
       
   324     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::HandleTermination()" )
       
   325     }
       
   326 
       
   327 
       
   328 // -----------------------------------------------------------------------------
       
   329 // Sets payload type and calls overridden base class version
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CMusEngMceOutSession::AdjustVideoCodecL( CMceVideoCodec& aVideoCodec )
       
   333     {
       
   334     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::AdjustVideoCodecL()" )
       
   335     
       
   336     CMusEngMceSession::AdjustVideoCodecL( aVideoCodec );
       
   337     
       
   338     if ( aVideoCodec.SdpName() == KMceSDPNameH263() ||
       
   339          aVideoCodec.SdpName() == KMceSDPNameH2632000() )
       
   340         {
       
   341         User::LeaveIfError( 
       
   342                 aVideoCodec.SetPayloadType( KMusEngPayloadTypeVideoH263 ) );
       
   343         }
       
   344     else if ( aVideoCodec.SdpName() == KMceSDPNameH264() )
       
   345         {
       
   346         User::LeaveIfError(
       
   347                 aVideoCodec.SetPayloadType( KMusEngPayloadTypeVideoAvc ) );
       
   348         }
       
   349     else
       
   350         {
       
   351         // NOP
       
   352         }
       
   353     
       
   354     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::AdjustVideoCodecL()" )
       
   355     }
       
   356 
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // Sets payload type and calls overridden base class version
       
   360 // -----------------------------------------------------------------------------
       
   361 //        
       
   362 void CMusEngMceOutSession::AdjustAudioCodecL( CMceAudioCodec& aAudioCodec )
       
   363     {
       
   364     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::AdjustAudioCodecL()" )
       
   365     
       
   366     CMusEngMceSession::AdjustAudioCodecL( aAudioCodec );
       
   367     
       
   368     User::LeaveIfError( aAudioCodec.SetPayloadType( KMusEngPayloadTypeAudio ) );
       
   369     
       
   370     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::AdjustAudioCodecL()" )
       
   371     }
       
   372         
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 //
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 CMusEngMceOutSession::CMusEngMceOutSession( 
       
   379                                 const TRect& aRect,
       
   380                                 MMusEngSessionObserver& aSessionObserver,
       
   381                                 MMusEngOutSessionObserver& aOutSessionObserver )
       
   382     : CMusEngMceSession( aRect, aSessionObserver ),      
       
   383       iOutSessionObserver( aOutSessionObserver )
       
   384     {
       
   385     }
       
   386 
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 void CMusEngMceOutSession::ConstructL( TUint aSipProfileId )
       
   393     {
       
   394     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::ConstructL()" )
       
   395 
       
   396     CMusEngMceSession::ConstructL();
       
   397     iSipProfileHandler->CreateProfileL( aSipProfileId );
       
   398     
       
   399     // Check if feature specific behavior is expected
       
   400     iPrivate = ( MultimediaSharingSettings::PrivacySetting());
       
   401         
       
   402     NMusSessionInformationApi::TMusClirSetting clir;
       
   403     // Ignore RProperty::Get return value.Incase of error it should behave default.
       
   404     RProperty::Get( NMusSessionInformationApi::KCategoryUid,
       
   405                     NMusSessionInformationApi::KMusClirSetting,
       
   406                     reinterpret_cast<TInt&>( clir ) );
       
   407     iPrivateNumber = ( clir == NMusSessionInformationApi::ESendOwnNumber )? EFalse: ETrue;
       
   408       
       
   409     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::ConstructL()" )
       
   410     }
       
   411 
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 // -----------------------------------------------------------------------------
       
   416 //
       
   417 void CMusEngMceOutSession::CreateMceSessionStructureL()
       
   418     {
       
   419     MUS_LOG( "mus: [ENGINE]  -> CMusEngMceOutSession::CreateMceSessionStructureL()" )
       
   420 
       
   421  	CSIPProfile* profile = iSipProfileHandler->Profile();
       
   422     __ASSERT_ALWAYS( profile != NULL, User::Leave( KErrNotReady ) );
       
   423 
       
   424     // Create session
       
   425     if ( iPrivate && iPrivateNumber )
       
   426         {
       
   427         HBufC8* originator = KMusAnonymousHeader().AllocLC();
       
   428         iSession = CMceOutSession::NewL( *iManager, *profile, *iRecipient, originator );
       
   429         CleanupStack::Pop();
       
   430         }
       
   431     else
       
   432         {
       
   433         iSession = CMceOutSession::NewL( *iManager, *profile, *iRecipient );
       
   434         }
       
   435 
       
   436 
       
   437     // Remove QoS-lines if needed
       
   438     if ( profile->Type().iSIPProfileClass == 
       
   439          TSIPProfileTypeInfo::EInternet ||
       
   440          MultimediaSharingSettings::ForceInternetSignalingSettingL() ==
       
   441          MusSettingsKeys::EForceInternetSignaling ||
       
   442          iOperatorVariant)
       
   443         {
       
   444         iSession->SetModifierL( KMcePreconditions, KMcePreconditionsNotUsed );
       
   445         MUS_LOG( "mus: [ENGINE]     Usage of preconditions denied" )
       
   446         }
       
   447         
       
   448     SetSessionSdpLinesL( *iSession );
       
   449 
       
   450     // Create bundle for local streams
       
   451     
       
   452     CMceStreamBundle* localBundle = 
       
   453                         CMceStreamBundle::NewLC( CMceStreamBundle::ELS );
       
   454 
       
   455     // To complete session structure, let the sibling classes add video out
       
   456     // and possibly needed audio streams
       
   457     CompleteSessionStructureL( *localBundle );
       
   458 
       
   459     // Create stream to display and share source with video outstream
       
   460     CMceVideoStream* streamForDisplay = CMceVideoStream::NewLC();
       
   461 
       
   462     CMceVideoStream* videoOut = MusEngMceUtils::GetVideoOutStreamL( *iSession );
       
   463     
       
   464     SetMediaSdpLinesL( *videoOut );
       
   465 		
       
   466     streamForDisplay->SetSourceL( videoOut->Source() );
       
   467 
       
   468     MusEngMceUtils::AddDisplayL( *streamForDisplay, *iManager, Rect() );
       
   469 
       
   470     iSession->AddStreamL( streamForDisplay );
       
   471     CleanupStack::Pop( streamForDisplay );    
       
   472 
       
   473     // Check if there are audio streams to bundle with
       
   474     if ( localBundle->Streams().Count() > 0 ) 
       
   475         {
       
   476         localBundle->AddStreamL( *streamForDisplay );
       
   477         iSession->AddBundleL( localBundle );
       
   478         CleanupStack::Pop( localBundle );
       
   479         }
       
   480     else
       
   481         {
       
   482         CleanupStack::PopAndDestroy( localBundle );
       
   483         }
       
   484 
       
   485     MUS_LOG( "mus: [ENGINE]  <- CMusEngMceOutSession::CreateMceSessionStructureL()" )
       
   486     }
       
   487 
       
   488 
       
   489 // -----------------------------------------------------------------------------
       
   490 // Add Privacy header if own phone number/id should not be sent to remote party
       
   491 // -----------------------------------------------------------------------------
       
   492 //
       
   493 void CMusEngMceOutSession::AddPrivacyHeaderL( CDesC8Array& aHeaders )
       
   494     {
       
   495     MUS_LOG( "mus: [ENGINE]  -> AddPrivacyHeaderL()" )
       
   496     _LIT8( KMusPrivacyHeaderValue, "id" );
       
   497     CSIPExtensionHeader* header = CSIPExtensionHeader::NewLC( 
       
   498                                   KMusPrivacyHeader, KMusPrivacyHeaderValue );
       
   499     HBufC8* headInText = header->ToTextL();
       
   500     MUS_LOG_TDESC8( " mus: [ENGINE] Privacy header : ", headInText->Des() );
       
   501     CleanupStack::PopAndDestroy( header );
       
   502     CleanupStack::PushL( headInText );
       
   503     aHeaders.AppendL( *headInText );
       
   504     CleanupStack::PopAndDestroy( headInText );
       
   505     MUS_LOG( "mus: [ENGINE]  <- AddPrivacyHeaderL()" )
       
   506     }