voipplugins/sipmxresolver/src/sipmxresolver.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
equal deleted inserted replaced
20:65a3ef1d5bd0 21:f742655b05bf
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  implementation of sipmxresolver
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "sipmxresolver.h"
       
    21 #include "csipclientresolverutils.h"
       
    22 #include <e32base.h>
       
    23 #include <e32std.h>
       
    24 #include <e32property.h>
       
    25 
       
    26 //for checking CS call status
       
    27 #include <ctsydomainpskeys.h>
       
    28 
       
    29 //SIP message content parsing APIs
       
    30 #include <sipheaderbase.h>
       
    31 #include <sipacceptcontactheader.h>
       
    32 #include <sipaddress.h>
       
    33 #include <sdpdocument.h>
       
    34 #include <sdpmediafield.h>
       
    35 #include <sdpcodecstringpool.h>
       
    36 #include <sdpcodecstringconstants.h>
       
    37 #include <sdpattributefield.h>
       
    38 #include <sipstrings.h>
       
    39 #include <sipallowheader.h>
       
    40 #include <sipsupportedheader.h>
       
    41 
       
    42 //For checking dynamic voip status and MuS availability
       
    43 #include <featmgr.h>
       
    44 #include <centralrepository.h>
       
    45 #include <settingsinternalcrkeys.h>
       
    46 
       
    47 //Multimedia Sharing client API
       
    48 #include <musmanager.h>
       
    49 
       
    50 //Incoming Call Monitor API
       
    51 #include <icmapi.h>
       
    52 
       
    53 
       
    54 // CONSTANTS
       
    55 _LIT8( KFTagChar, "+" ); 						// All feature tags start with +
       
    56 _LIT8( KVSFeatureTag, "+g.3gpp.cs-voice" );		// For checking VS specific tag
       
    57 _LIT8( KPoCFeatureTag, "+g.poc.talkburst" ); 	// PoC specific tag (for ruling out)
       
    58 _LIT8( KContentType, "application/sdp" );		// For content-type header
       
    59 _LIT8( KMediaTypeApp, "application" );        	// For content-type header checks
       
    60 _LIT8( KMediaSubtypeSdp, "sdp" );            	// For content-type header checks
       
    61 _LIT8( KSendOnly, "sendonly" );            		// For attribute checks
       
    62 _LIT8( KApplicationAttr, "application" );   	// For attribute checks
       
    63 _LIT8( KXApplicationAttr, "X-application" );	// For attribute checks
       
    64 _LIT8( KNokiaRtvs, "com.nokia.rtvs" );       	// For attribute checks
       
    65 _LIT8( KSIPMethodsInAllowHeader, "INVITE,ACK,CANCEL,OPTIONS,BYE,PRACK,SUBSCRIBE,REFER,NOTIFY,UPDATE");	// SIP Methods allowed by various plugins
       
    66 _LIT8( KSIPExtensionsSupported, "100rel,timer,sec-agree"); //Extensions supported by various plugins
       
    67 
       
    68 /**
       
    69  * Cleanup function for RPointerArray
       
    70  * Called in case of a leave in SupportedSdpMediasL
       
    71  */
       
    72 void CleanupSdpMediasArray( TAny* aObj )
       
    73     {
       
    74     if ( aObj )
       
    75         {
       
    76         static_cast<RPointerArray<CSdpMediaField>*>( aObj )->ResetAndDestroy();
       
    77         }
       
    78     }
       
    79 
       
    80 
       
    81 // ============================ MEMBER FUNCTIONS =============================
       
    82 // ---------------------------------------------------------------------------
       
    83 // CSipMXResolver::CSipMXResolver
       
    84 // C++ default constructor can NOT contain any code, that
       
    85 // might leave.
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 CSipMXResolver::CSipMXResolver() 
       
    89     {
       
    90     }
       
    91 
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // CSipMXResolver::ConstructL
       
    95 // Symbian 2nd phase constructor can leave.
       
    96 // ---------------------------------------------------------------------------
       
    97 // 
       
    98 void CSipMXResolver::ConstructL()
       
    99     {
       
   100     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::ConstructL()" )
       
   101     
       
   102     // Open sdp string pool (needed in media field checks)
       
   103     TRAPD( err, SdpCodecStringPool::OpenL() );
       
   104     
       
   105     switch ( err )
       
   106 	    {
       
   107     	case KErrNone:
       
   108 	    	{
       
   109 	    	//close pool at destructor, not opened by others
       
   110 			iCloseStringPool = ETrue;
       
   111 			break;
       
   112 	    	}
       
   113 	    
       
   114 	    case KErrAlreadyExists:
       
   115 	    	{
       
   116 	    	//already opened, do not try to close at destructor
       
   117 	    	iCloseStringPool = EFalse;
       
   118 	    	break;
       
   119 	    	}
       
   120 	    
       
   121 	    default:
       
   122 	    	{
       
   123 	    	User::Leave( err );
       
   124 	    	}
       
   125 	    }
       
   126     
       
   127     // Check VoIP and Multimedia Sharing availability
       
   128     FeatureManager::InitializeLibL();
       
   129     
       
   130     TInt dynvoip = 0;
       
   131     CRepository* repository = CRepository::NewL( KCRUidTelephonySettings );
       
   132     repository->Get( KDynamicVoIP, dynvoip );
       
   133     delete repository;
       
   134     
       
   135     iVoIPEnabled = ( dynvoip && FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) );
       
   136     
       
   137     if ( FeatureManager::FeatureSupported( KFeatureIdMultimediaSharing ) )
       
   138         {
       
   139         iMuSManager = CMusManager::NewL();
       
   140         }
       
   141     
       
   142     FeatureManager::UnInitializeLib();
       
   143     
       
   144     // initialize media type strings
       
   145     iAudioType = SdpCodecStringPool::StringPoolL().StringF(
       
   146                     SdpCodecStringConstants::EMediaAudio,
       
   147                         SdpCodecStringPool::StringTableL() );
       
   148     
       
   149     iVideoType = SdpCodecStringPool::StringPoolL().StringF(
       
   150                     SdpCodecStringConstants::EMediaVideo,
       
   151                         SdpCodecStringPool::StringTableL() );
       
   152     
       
   153     SIPMXRLOG( "[SIPMXRESOLVER] <- CSipMXResolver::ConstructL()" )
       
   154     }
       
   155 
       
   156 
       
   157 // ---------------------------------------------------------------------------
       
   158 // CSipMXResolver::NewL
       
   159 // Two-phased constructor.
       
   160 // ---------------------------------------------------------------------------
       
   161 // 
       
   162 CSipMXResolver* CSipMXResolver::NewL()
       
   163     {
       
   164     CSipMXResolver* self = new( ELeave ) CSipMXResolver;
       
   165     CleanupStack::PushL( self );
       
   166     self->ConstructL();
       
   167     CleanupStack::Pop( self);
       
   168     return self;
       
   169     }
       
   170 
       
   171 
       
   172 // Destructor
       
   173 CSipMXResolver::~CSipMXResolver()
       
   174     {
       
   175     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::~CSipMXResolver()" )
       
   176     
       
   177     delete iMuSManager;
       
   178     iAudioType.Close();
       
   179     iVideoType.Close();
       
   180     
       
   181     if ( iCloseStringPool )
       
   182 	    {
       
   183 	    SdpCodecStringPool::Close();
       
   184 	    }
       
   185     
       
   186     SIPMXRLOG( "[SIPMXRESOLVER] <- CSipMXResolver::~CSipMXResolver()" )
       
   187     }
       
   188 
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // CSipMXResolver::MatchAcceptContactsL
       
   192 // ---------------------------------------------------------------------------
       
   193 // 
       
   194 TBool CSipMXResolver::MatchAcceptContactsL(
       
   195             RStringF aMethod,
       
   196             const CUri8& /*aRequestUri*/,
       
   197             const RPointerArray<CSIPHeaderBase>& aHeaders,
       
   198             const TDesC8& /*aContent*/,
       
   199             const CSIPContentTypeHeader* /*aContentType*/,
       
   200             TUid& aClientUid )
       
   201     {
       
   202     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::MatchAcceptContactsL()" )
       
   203     
       
   204     TBool match = EFalse;
       
   205     
       
   206     // check if we have active CS call
       
   207     // and MM Sharing is enabled (otherwise this can't be MuS)
       
   208     if ( iMuSManager && IsCSCallActive() )
       
   209         {
       
   210         if ( CheckForACHeaderTagL( aHeaders, KVSFeatureTag ) )
       
   211             {
       
   212             match = ETrue;
       
   213             aClientUid = ResolveVSUidL( aMethod );
       
   214             }
       
   215         }
       
   216     
       
   217     SIPMXRLOGP( \
       
   218     "[SIPMXRESOLVER] <- CSipMXResolver::MatchAcceptContactsL(), ret:%d", match )
       
   219     return match;
       
   220     }
       
   221 
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // CSipMXResolver::MatchEventL
       
   225 // ---------------------------------------------------------------------------
       
   226 // 
       
   227 TBool CSipMXResolver::MatchEventL(
       
   228             RStringF /*aMethod*/,
       
   229             const CUri8& /*aRequestUri*/,
       
   230             const RPointerArray<CSIPHeaderBase>& /*aHeaders*/,
       
   231             const TDesC8& /*aContent*/,
       
   232             const CSIPContentTypeHeader* /*aContentType*/,
       
   233             TUid& /*aClientUid*/)
       
   234     {
       
   235     //SipMXResolver returns always EFalse for MatchEventL calls
       
   236     SIPMXRLOG( "[SIPMXRESOLVER] <-> CSipMXResolver::MatchEventL()" )
       
   237     return EFalse;
       
   238     }
       
   239 
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // CSipMXResolver::MatchRequestL
       
   243 // ---------------------------------------------------------------------------
       
   244 // 
       
   245 TBool CSipMXResolver::MatchRequestL(
       
   246             RStringF aMethod,
       
   247             const CUri8& aRequestUri,
       
   248             const RPointerArray<CSIPHeaderBase>& aHeaders,
       
   249             const TDesC8& aContent,
       
   250             const CSIPContentTypeHeader* aContentType,
       
   251             TUid& aClientUid )
       
   252     {
       
   253     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::MatchRequestL()" )
       
   254     
       
   255     TBool match = EFalse;
       
   256     
       
   257     //poc specific requests will not be processed
       
   258     TBool poc = CheckForACHeaderTagL( aHeaders, KPoCFeatureTag );
       
   259     
       
   260     //OPTIONS and INVITE requests are processed
       
   261     TBool requestok = ( aMethod == SIPStrings::StringF( SipStrConsts::EOptions ) ||
       
   262          aMethod == SIPStrings::StringF( SipStrConsts::EInvite ) );
       
   263     
       
   264     //application/sdp content type is required
       
   265     TBool contentok = ( aContent.Length() > 0 && aContentType &&
       
   266          aContentType->MediaType().CompareF( KMediaTypeApp ) == 0 &&
       
   267          aContentType->MediaSubtype().CompareF( KMediaSubtypeSdp ) == 0 );
       
   268     
       
   269     // do further checks only if we have either VoIP and/or MuS active,
       
   270     // content type must be valid and accept-contact is not poc specific
       
   271     if ( ( iVoIPEnabled || iMuSManager ) && requestok && contentok && !poc )
       
   272         {
       
   273         CSdpDocument* sdpDocument = CSdpDocument::DecodeLC( aContent );
       
   274         
       
   275         // determine the parameters
       
   276         TBool hasAudio = CheckForMedia( sdpDocument, iAudioType );
       
   277         TBool hasVideo = CheckForMedia( sdpDocument, iVideoType );
       
   278         TBool cscall = IsCSCallActive();
       
   279         
       
   280         if ( iMuSManager && hasVideo && hasAudio && cscall )
       
   281             {
       
   282             // both audio and video medias present and cs call on
       
   283             // and multimedia sharing enabled =>
       
   284             // we need to do some further resolving for client
       
   285             if ( CheckForVSAttributes( sdpDocument->MediaFields() ) )
       
   286                 {
       
   287                 // this is VS
       
   288                 match = ETrue;
       
   289                 aClientUid = ResolveVSUidL( aMethod );
       
   290                 }
       
   291             else if ( iVoIPEnabled )
       
   292                 {
       
   293                 // no vs attributes and voip status is enabled
       
   294                 match = ETrue;
       
   295                 ResolveCPPluginUidL( aClientUid, aRequestUri );
       
   296                 }
       
   297             else
       
   298                 {
       
   299                 // possible voip match, but voip not activated
       
   300                 match = EFalse;
       
   301                 }
       
   302             }
       
   303         else if ( iMuSManager && hasVideo && cscall )
       
   304             {
       
   305             //video media only && cs call ongoing && multimedia sharing enabled
       
   306             // => Multimedia Sharing
       
   307             match = ETrue;
       
   308             aClientUid = ResolveVSUidL( aMethod );
       
   309             }
       
   310         else if ( hasAudio && iVoIPEnabled )
       
   311             {
       
   312             // audio only or audio and video and no cs call + voip supported
       
   313             // => this is VoIP
       
   314             match = ETrue;
       
   315             ResolveCPPluginUidL( aClientUid, aRequestUri );
       
   316             }
       
   317         else
       
   318             {
       
   319             // no medias or has video but no CS call or has audio
       
   320             // but voip status is disabled 
       
   321             // => no match
       
   322             match = EFalse;
       
   323             }
       
   324         
       
   325         CleanupStack::PopAndDestroy( sdpDocument );
       
   326         }
       
   327     else if ( aMethod == SIPStrings::StringF( SipStrConsts::EInvite ) &&
       
   328     		  iVoIPEnabled && !poc && aContent.Length() == 0 )
       
   329     	{
       
   330     	// Pull model: this is a re-Invite without content
       
   331     	ResolveCPPluginUidL( aClientUid, aRequestUri );
       
   332     	match = ETrue;
       
   333     	}
       
   334     else
       
   335     	{
       
   336     	//no match
       
   337     	match = EFalse;
       
   338         }
       
   339     
       
   340     SIPMXRLOGP( \
       
   341     "[SIPMXRESOLVER] <- CSipMXResolver::MatchRequestL(), ret:%d", match )
       
   342     return match;
       
   343     }
       
   344 
       
   345 
       
   346 // ---------------------------------------------------------------------------
       
   347 // CSipMXResolver::ConnectSupported
       
   348 // ---------------------------------------------------------------------------
       
   349 // 
       
   350 TBool CSipMXResolver::ConnectSupported()
       
   351     {
       
   352     return ETrue;
       
   353     }
       
   354 
       
   355 
       
   356 // ---------------------------------------------------------------------------
       
   357 // CSipMXResolver::ConnectL
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 void CSipMXResolver::ConnectL( const TUid& aClientUid )
       
   361     {
       
   362     SIPMXRLOGP(\
       
   363     "[SIPMXRESOLVER] -> CSipMXResolver::ConnectL(), uid:%d", aClientUid.iUid )
       
   364     
       
   365     // If Uid matches with MuS, forward to MusManager
       
   366     if ( iMuSManager &&
       
   367          ( aClientUid.iUid == CMusManager::ESipOptions ||
       
   368            aClientUid.iUid == CMusManager::ESipInviteDesired ||
       
   369            aClientUid.iUid == CMusManager::ESipInviteNotDesired ) )
       
   370         {
       
   371         iMuSManager->HandleSipRequestL(
       
   372                   ( CMusManager::TRequestType ) aClientUid.iUid );
       
   373         }
       
   374     else
       
   375         {
       
   376         // start through ICM
       
   377         TInt result = RProperty::Set( KPSUidICMIncomingCall,
       
   378         		KPropertyKeyICMPluginUID, aClientUid.iUid );
       
   379         User::LeaveIfError( result );
       
   380         }
       
   381     
       
   382     SIPMXRLOG( "[SIPMXRESOLVER] <- CSipMXResolver::ConnectL()" )
       
   383     }
       
   384 
       
   385 
       
   386 // ---------------------------------------------------------------------------
       
   387 // CSipMXResolver::CancelConnect
       
   388 // ---------------------------------------------------------------------------
       
   389 // 
       
   390 void CSipMXResolver::CancelConnect( const TUid& /*aClientUid*/ )
       
   391     {
       
   392     SIPMXRLOG( "[SIPMXRESOLVER] <-> CSipMXResolver::CancelConnect()" )
       
   393     // No implementation for VoIP / MuS.
       
   394     }
       
   395 
       
   396 
       
   397 // ---------------------------------------------------------------------------
       
   398 // CSipMXResolver::SupportedContentTypesL
       
   399 // ---------------------------------------------------------------------------
       
   400 // 
       
   401 RPointerArray<CSIPContentTypeHeader> CSipMXResolver::SupportedContentTypesL()
       
   402     {
       
   403     RPointerArray<CSIPContentTypeHeader> ret;
       
   404     
       
   405     CSIPContentTypeHeader* ctype = CSIPContentTypeHeader::DecodeL( KContentType );
       
   406     CleanupStack::PushL( ctype );
       
   407     ret.AppendL( ctype );
       
   408     CleanupStack::Pop( ctype );
       
   409     
       
   410     return ret;
       
   411     }
       
   412 
       
   413 
       
   414 // ---------------------------------------------------------------------------
       
   415 // CSipMXResolver::SupportedSdpMediasL
       
   416 // ---------------------------------------------------------------------------
       
   417 // 
       
   418 RPointerArray<CSdpMediaField> CSipMXResolver::SupportedSdpMediasL()
       
   419     {
       
   420     // Initialise return array
       
   421     RPointerArray<CSdpMediaField> ret;
       
   422     TCleanupItem tci( CleanupSdpMediasArray, &ret );
       
   423     CleanupStack::PushL( tci );
       
   424     
       
   425     // media field descriptors
       
   426     _LIT8( KMuSField1, "m=video 0 RTP/AVP 96\r\na=application:com.nokia.rtvs\r\na=X-application:com.nokia.rtvs\r\n" );
       
   427     _LIT8( KMuSField2, "m=audio 0 RTP/AVP 97\r\n" );
       
   428     _LIT8( KVoIPField1, "m=video 0 RTP/AVP 0\r\n" );
       
   429     _LIT8( KVoIPField2, "m=application 0 tcp wb\r\n" );
       
   430     _LIT8( KVoIPField3, "m=audio 0 RTP/AVP 0\r\n" );
       
   431     _LIT8( KVoIPField4, "m=audio 0 RTP/SAVP 0\r\n" );
       
   432     
       
   433     CSdpMediaField* field = NULL;
       
   434     
       
   435     // add media fields to array
       
   436     if ( iMuSManager )
       
   437         {
       
   438         field = CSdpMediaField::DecodeLC( KMuSField1 );
       
   439         ret.AppendL( field ); // ownership to array
       
   440         CleanupStack::Pop( field );
       
   441         
       
   442         field = CSdpMediaField::DecodeLC( KMuSField2 );
       
   443         ret.AppendL( field );
       
   444         CleanupStack::Pop( field );
       
   445         }
       
   446     
       
   447     if ( iVoIPEnabled )
       
   448         {
       
   449         field = CSdpMediaField::DecodeLC( KVoIPField1 );
       
   450         ret.AppendL( field );
       
   451         CleanupStack::Pop( field );
       
   452         
       
   453         field = CSdpMediaField::DecodeLC( KVoIPField2 );
       
   454         ret.AppendL( field );
       
   455         CleanupStack::Pop( field );
       
   456         
       
   457         field = CSdpMediaField::DecodeLC( KVoIPField3 );
       
   458         ret.AppendL( field );
       
   459         CleanupStack::Pop( field );
       
   460         
       
   461         field = CSdpMediaField::DecodeLC( KVoIPField4 );
       
   462         ret.AppendL( field );
       
   463         CleanupStack::Pop( field );
       
   464         }
       
   465     
       
   466     CleanupStack::Pop(); // tcleanupitem
       
   467     return ret;
       
   468     }
       
   469 
       
   470 
       
   471 // ---------------------------------------------------------------------------
       
   472 // CSipMXResolver::AddClientSpecificHeadersForOptionsResponseL
       
   473 // ---------------------------------------------------------------------------
       
   474 // 
       
   475 void CSipMXResolver::AddClientSpecificHeadersForOptionsResponseL(
       
   476     RPointerArray<CSIPHeaderBase>& aHeaders )
       
   477     {
       
   478     SIPMXRLOG( "[SIPMXRESOLVER] -> \
       
   479     CSipMXResolver::AddClientSpecificHeadersForOptionsResponseL()" )
       
   480 	//Add Allow Header		
       
   481 	RPointerArray<CSIPAllowHeader> allowheaders = 
       
   482 	    CSIPAllowHeader::DecodeL(KSIPMethodsInAllowHeader);
       
   483 	TInt count = allowheaders.Count();
       
   484 	for(TInt i = 0; i<count; i++)
       
   485 		{
       
   486 		User::LeaveIfError(aHeaders.Append(allowheaders[i]));
       
   487 		}
       
   488 	allowheaders.Reset();
       
   489 
       
   490 	//Add Supported Header
       
   491 	RPointerArray<CSIPSupportedHeader> supportedheaders = 
       
   492 	    CSIPSupportedHeader::DecodeL(KSIPExtensionsSupported);
       
   493 	count = supportedheaders.Count();
       
   494 	for(TInt j = 0; j<count; j++)
       
   495 		{
       
   496 		User::LeaveIfError(aHeaders.Append(supportedheaders[j]));
       
   497 		}
       
   498 	supportedheaders.Reset();
       
   499     }
       
   500 
       
   501 
       
   502 // ---------------------------------------------------------------------------
       
   503 // CSipMXResolver::IsCsCallActive
       
   504 // ---------------------------------------------------------------------------
       
   505 // 
       
   506 TBool CSipMXResolver::IsCSCallActive() const
       
   507     {
       
   508     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::IsCSCallActive()" )
       
   509     
       
   510     TBool retval = EFalse;
       
   511     
       
   512     TInt callType = KErrNone;
       
   513     RProperty::Get( KPSUidCtsyCallInformation,
       
   514     		KCTsyCallType, callType );
       
   515     
       
   516     if ( EPSCTsyCallTypeCSVoice == callType )
       
   517         {
       
   518         TInt callState = KErrNone;
       
   519         RProperty::Get( KPSUidCtsyCallInformation,
       
   520         		KCTsyCallState, callState );
       
   521         
       
   522         if ( EPSCTsyCallStateConnected == callState ||
       
   523              EPSCTsyCallStateHold == callState )
       
   524             {
       
   525             retval = ETrue;
       
   526             }
       
   527         }
       
   528     
       
   529     SIPMXRLOGP( \
       
   530     "[SIPMXRESOLVER] <- CSipMXResolver::IsCSCallActive(), ret:%d", retval )
       
   531     
       
   532     return retval;
       
   533     }
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CSipMXResolver::CheckForMedia
       
   537 // -----------------------------------------------------------------------------
       
   538 //
       
   539 TBool CSipMXResolver::CheckForMedia( CSdpDocument* aSdpDoc,
       
   540     const RStringF& aMediaType ) const
       
   541     {
       
   542     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::CheckForMedia()" )
       
   543     
       
   544     TBool present = EFalse;
       
   545     
       
   546     if ( aSdpDoc )
       
   547         {
       
   548         RPointerArray<CSdpMediaField>& mFields = aSdpDoc->MediaFields();
       
   549         const TInt count = mFields.Count();
       
   550         
       
   551         // if there is media fields, check them for type
       
   552         for ( TInt i = 0; i < count && !present; i++ )
       
   553             {
       
   554             if ( aMediaType == mFields[ i ]->Media() )
       
   555                 {
       
   556                 present = ETrue;
       
   557                 }
       
   558             }
       
   559         }
       
   560     
       
   561     SIPMXRLOGP( \
       
   562     "[SIPMXRESOLVER] <- CSipMXResolver::CheckForMedia(), ret:%d", present )
       
   563     
       
   564     return present;
       
   565     }
       
   566 
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 // CSipMXResolver::CheckForACHeaderTagL
       
   570 // ---------------------------------------------------------------------------
       
   571 // 
       
   572 TBool CSipMXResolver::CheckForACHeaderTagL(
       
   573     const RPointerArray<CSIPHeaderBase>& aHeaders,
       
   574     const TDesC8& aTag ) const
       
   575     {
       
   576     TBool match = EFalse;
       
   577     TInt ftagcount = 0;
       
   578     
       
   579     for ( TInt i = 0; i < aHeaders.Count(); i++ )
       
   580         {
       
   581         if ( aHeaders[i]->Name() ==
       
   582              SIPStrings::StringF( SipStrConsts::EAcceptContactHeader ) ||
       
   583              aHeaders[i]->Name() ==
       
   584              SIPStrings::StringF( SipStrConsts::EAcceptContactHeaderCompact ) )
       
   585             {
       
   586             RStringF featureTagStr = SIPStrings::Pool().OpenFStringL( aTag );
       
   587             CleanupClosePushL( featureTagStr );
       
   588             
       
   589             CSIPAcceptContactHeader* ach = 
       
   590                 static_cast<CSIPAcceptContactHeader*>(aHeaders[i]);
       
   591             TInt pcount = ach->ParamCount();
       
   592             
       
   593             for ( TInt p = 0; p < pcount; p++ )
       
   594                 {
       
   595                 RStringF mparam;
       
   596                 CleanupClosePushL( mparam );
       
   597                 
       
   598                 if ( KErrNone == ach->Param( p, mparam ) )
       
   599                     {
       
   600                     //we need to count all feature tags
       
   601                     if ( mparam.DesC().Left(1).Compare( KFTagChar ) == 0 )
       
   602                         {
       
   603                         ftagcount++;
       
   604                         }
       
   605                     if ( mparam == featureTagStr )
       
   606                         {
       
   607                         match = ETrue;
       
   608                         //loop is continued after match to count feature tags
       
   609                         }
       
   610                     }
       
   611                 
       
   612                 CleanupStack::PopAndDestroy( 1 ); //mparam
       
   613                 }
       
   614             
       
   615             // Use the dynamic string.
       
   616             CleanupStack::PopAndDestroy( 1 ); // featureTagStr
       
   617             }
       
   618         }
       
   619     
       
   620     //return ETrue only if there's only one feature tag and it is MuS specific
       
   621     return ( match && ftagcount == 1 );
       
   622     }
       
   623 
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 // CSipMXResolver::CheckForVSAttributesL
       
   627 // ---------------------------------------------------------------------------
       
   628 // 
       
   629 TBool CSipMXResolver::CheckForVSAttributes(
       
   630     RPointerArray<CSdpMediaField>& aFields ) const
       
   631     {
       
   632     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::CheckForVSAttributes()" )
       
   633     
       
   634     TBool vsattributefound = EFalse;
       
   635     TInt sendonlycount = 0; 
       
   636     TInt videofields = 0;
       
   637     const TInt fieldcount = aFields.Count();
       
   638     
       
   639     for ( TInt i = 0; i < fieldcount; i++ )
       
   640         {
       
   641         CSdpMediaField* mField = aFields[i];
       
   642         
       
   643         //only check audio/video fields
       
   644         TBool audio = mField->Media() == iAudioType;
       
   645         TBool video = mField->Media() == iVideoType;
       
   646         
       
   647         if ( video )
       
   648             {
       
   649             videofields++;
       
   650             }
       
   651         
       
   652         if ( video || audio )
       
   653             {
       
   654             RPointerArray< CSdpAttributeField > attrList =
       
   655                 mField->AttributeFields();
       
   656             
       
   657             TInt attrCount = attrList.Count();
       
   658             for (TInt j = 0; j < attrCount && !vsattributefound; j++ )
       
   659                 {
       
   660                 CSdpAttributeField* attributeField = attrList[j];
       
   661                 RStringF attribute = attributeField->Attribute();
       
   662                 
       
   663                 // for each sendonly attribute, add counter
       
   664                 if ( KErrNotFound != attribute.DesC().FindF( KSendOnly ) )
       
   665                     {
       
   666                     sendonlycount++;                        
       
   667                     }
       
   668                 
       
   669                 // check m=video fields for com.nokia.rtvs attribute
       
   670                 if ( video )
       
   671                     {
       
   672                     if ( ( KErrNotFound !=
       
   673                            attribute.DesC().FindF( KApplicationAttr ) ||
       
   674                            KErrNotFound !=
       
   675                            attribute.DesC().FindF( KXApplicationAttr ) ) &&
       
   676                          KErrNotFound !=
       
   677                          attributeField->Value().FindF( KNokiaRtvs ) )
       
   678                         {
       
   679                         //attribute found
       
   680                         vsattributefound = ETrue;
       
   681                         }
       
   682                     }
       
   683                 }
       
   684             }
       
   685         }
       
   686     
       
   687     // Video Sharing is assumed if nokia vs specific attributes are found
       
   688     // or if there is at least one m=video line and all media fields have
       
   689     // sendonly attribute.
       
   690     TBool retval = ( vsattributefound ||
       
   691         		     ( videofields > 0 && fieldcount == sendonlycount ) );
       
   692     
       
   693     SIPMXRLOGP( \
       
   694     "[SIPMXRESOLVER] <- CSipMXResolver::CheckForVSAttributes(),ret:%d", retval )
       
   695     
       
   696     return retval;
       
   697     }
       
   698 
       
   699 
       
   700 // ---------------------------------------------------------------------------
       
   701 // CSipMXResolver::ResolveVSUid
       
   702 // ---------------------------------------------------------------------------
       
   703 // 
       
   704 TUid CSipMXResolver::ResolveVSUidL( const RStringF& aMethod )
       
   705     {
       
   706     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::ResolveVSUidL()" )
       
   707     
       
   708     TUid muid  = KNullUid;
       
   709     
       
   710     if ( iMuSManager )
       
   711         {
       
   712         if ( aMethod == SIPStrings::StringF( SipStrConsts::EOptions ) )
       
   713             {
       
   714             muid.iUid = ( TInt32 ) CMusManager::ESipOptions;
       
   715             }
       
   716         else
       
   717             {
       
   718             MultimediaSharing::TMusAvailabilityStatus capability =
       
   719             	iMuSManager->AvailabilityL();
       
   720             
       
   721             //check if availability value is from non-error-range
       
   722             if( capability >= KErrNone &&
       
   723                 capability < MultimediaSharing::EErrSipRegistration )
       
   724                 {
       
   725                 muid.iUid = ( TInt32 ) CMusManager::ESipInviteDesired;
       
   726                 }
       
   727             else
       
   728                 {
       
   729                 muid.iUid = ( TInt32 ) CMusManager::ESipInviteNotDesired;
       
   730                 }
       
   731             }
       
   732         }
       
   733     
       
   734     SIPMXRLOGP( \
       
   735     "[SIPMXRESOLVER] <- CSipMXResolver::ResolveVSUidL(), ret:%d", muid.iUid )
       
   736     
       
   737     return muid;
       
   738     }
       
   739 
       
   740 
       
   741 // -----------------------------------------------------------------------------
       
   742 // CSipMXResolver::ResolveCPPluginUidL
       
   743 // -----------------------------------------------------------------------------
       
   744 // 
       
   745 void CSipMXResolver::ResolveCPPluginUidL( TUid& aUid, const CUri8& aRequestUri )
       
   746     {
       
   747     SIPMXRLOG( "[SIPMXRESOLVER] -> CSipMXResolver::ResolveCPPluginUidL()" )
       
   748     
       
   749     CSipClientResolverUtils* resolver = CSipClientResolverUtils::NewLC();
       
   750     resolver->GetImplementationUidWithUserL(
       
   751     		aRequestUri.Uri().Extract( EUriUserinfo ), aUid );
       
   752     CleanupStack::PopAndDestroy( resolver );
       
   753     
       
   754     SIPMXRLOGP( \
       
   755     "[SIPMXRESOLVER] <- CSipMXResolver::ResolveCPPluginUidL(),uID:%d", aUid.iUid )
       
   756     }
       
   757 
       
   758 
       
   759 //  End of File