mmsharing/mmshavailability/src/musavacapabilityquery.cpp
changeset 0 f0cf47e981f9
child 32 73a1feb507fb
equal deleted inserted replaced
-1:000000000000 0:f0cf47e981f9
       
     1 /*
       
     2 * Copyright (c) 2005-2007 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:   Sent SWIS capability query (OPTIONS)
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "musavacapabilityquery.h"
       
    20 #include "muslogger.h"
       
    21 #include "mussettings.h"
       
    22 #include "mussettingskeys.h"
       
    23 #include "musavacapability.h"
       
    24 #include "musavacapabilitycontext.h"
       
    25 #include "mussesseioninformationapi.h"
       
    26 #include "musavacapabilityexchange.h"
       
    27 #include "mmusavacapabilityqueryobserver.h"
       
    28 
       
    29 #include <sipconnection.h>
       
    30 #include <sipclienttransaction.h>
       
    31 #include <sipmessageelements.h>
       
    32 #include <sipresponseelements.h>
       
    33 #include <sdpdocument.h>
       
    34 #include <sipcontenttypeheader.h>
       
    35 #include <sdpattributefield.h>
       
    36 #include <sipcontactheader.h>
       
    37 #include <sipstrings.h>
       
    38 #include <sipaddress.h>
       
    39 #include <e32property.h>
       
    40 #include <escapeutils.h>
       
    41 #include <badesca.h>
       
    42 
       
    43 
       
    44 // --------------------------------------------------------------------------
       
    45 // C++ constructor
       
    46 // --------------------------------------------------------------------------
       
    47 //
       
    48 CMusAvaCapabilityQuery::CMusAvaCapabilityQuery(
       
    49                                         CMusAvaCapability& aCapability,
       
    50                                         CSIPConnection& aSIPConnection,
       
    51                                         CSIPProfile& aProfile )
       
    52  
       
    53     : CMusAvaCapabilityQueryBase( aCapability, aSIPConnection, aProfile ),
       
    54     iRetrying( EFalse )
       
    55     {
       
    56     }
       
    57  
       
    58 // --------------------------------------------------------------------------
       
    59 // Symbian two-phase constructor
       
    60 // --------------------------------------------------------------------------
       
    61 //
       
    62 CMusAvaCapabilityQuery* CMusAvaCapabilityQuery::NewL( 
       
    63                                         CMusAvaCapability& aCapability,
       
    64                                         CSIPConnection& aSIPConnection,
       
    65                                         CSIPProfile& aProfile,
       
    66                                         const TDesC& aSipAddress )
       
    67 
       
    68     {
       
    69     MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQuery::NewL" )
       
    70     
       
    71     CMusAvaCapabilityQuery* self = NULL;
       
    72     
       
    73     self = new (ELeave) CMusAvaCapabilityQuery( aCapability, 
       
    74                                             aSIPConnection,
       
    75                                             aProfile );
       
    76     CleanupStack::PushL( self );
       
    77     self->ConstructL( aSipAddress );
       
    78     CleanupStack::Pop( self );
       
    79   
       
    80     MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQuery::NewL" )
       
    81     return self;
       
    82     }
       
    83 
       
    84 // --------------------------------------------------------------------------
       
    85 // Symbian second-phase constructor
       
    86 // --------------------------------------------------------------------------
       
    87 //
       
    88 void CMusAvaCapabilityQuery::ConstructL( const TDesC& aSipAddress )
       
    89     {
       
    90     MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQuery::ConstructL" )
       
    91 
       
    92     CMusAvaCapabilityQueryBase::ConstructL( aSipAddress );
       
    93     
       
    94     MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQuery::ConstructL" )
       
    95     }
       
    96 
       
    97 // --------------------------------------------------------------------------
       
    98 // C++ destructor
       
    99 // --------------------------------------------------------------------------
       
   100 //
       
   101 CMusAvaCapabilityQuery::~CMusAvaCapabilityQuery()
       
   102     {
       
   103     MUS_LOG( 
       
   104         "mus: [MUSAVA] -> CMusAvaCapabilityQuery::~CMusAvaCapabilityQuery" )
       
   105 
       
   106     delete iTimer;
       
   107             
       
   108     MUS_LOG( 
       
   109         "mus: [MUSAVA] <- CMusAvaCapabilityQuery::~CMusAvaCapabilityQuery" )
       
   110     }
       
   111 
       
   112 // --------------------------------------------------------------------------
       
   113 // CMusAvaCapabilityQuery::Prepare
       
   114 // --------------------------------------------------------------------------
       
   115 //
       
   116 void CMusAvaCapabilityQuery::Prepare( 
       
   117                         RPointerArray<CSIPHeaderBase>& /*aRequestHeaders*/ )
       
   118     {
       
   119     MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQuery::Prepare" )
       
   120     
       
   121     if ( !Retrying() )
       
   122         {
       
   123         MUS_LOG( "mus: [MUSAVA] query prepared" )
       
   124         SetState( ECapabilityQueryPrepared );
       
   125         }
       
   126     
       
   127     MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQuery::Prepare" )
       
   128     }
       
   129 
       
   130 // --------------------------------------------------------------------------
       
   131 // CMusAvaCapabilityQuery::DoCompletedL
       
   132 // --------------------------------------------------------------------------
       
   133 //
       
   134 void CMusAvaCapabilityQuery::DoCompletedL( 
       
   135                                     const CSIPClientTransaction& aResponse )
       
   136     {
       
   137     MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQuery::DoCompletedL" )
       
   138     
       
   139     const CSIPResponseElements* response = aResponse.ResponseElements();
       
   140     User::LeaveIfError( !response ? KErrGeneral : KErrNone );
       
   141     
       
   142     TUint statusCode = response->StatusCode();
       
   143 
       
   144     MUS_LOG1( "mus: [MUSAVA] result %d", statusCode )
       
   145     
       
   146     switch ( statusCode )
       
   147         {
       
   148         case KMUSAVASIP200:
       
   149             {
       
   150             DoCompleted200OKL( aResponse ); 
       
   151             break;
       
   152             }
       
   153         case KMUSAVASIPNotImplemented:
       
   154             {
       
   155             MUS_LOG( "mus: [MUSAVA] => OK" )
       
   156             SetResult( KCapabilityCapabilitesReady );
       
   157             SetState( ECapabilityQueryCompleted );
       
   158             break;
       
   159             }
       
   160         case KMUSAVASIPForbidden:
       
   161             {
       
   162             MUS_LOG( "mus: [MUSAVA] => FAILED" )
       
   163             if ( MultimediaSharingSettings::OperatorVariantSettingL() ==
       
   164                   MusSettingsKeys::EOperatorSpecific )
       
   165                 {
       
   166                 SetResult( KCapabilityCapabilitiesForbidden );
       
   167                 SetState( ECapabilityQueryCompleted );
       
   168                 // set forbidden property
       
   169                 TInt result = 
       
   170                     RProperty::Set( 
       
   171                         NMusSessionInformationApi::KCategoryUid,
       
   172                         NMusSessionInformationApi::KMUSForbidden,
       
   173                         ( TInt ) NMusSessionInformationApi::EMUSForbidden );
       
   174                 MUS_LOG1( "mus: [MUSAVA]    Property::Ser( KMUSForbidden )\
       
   175                             returns %d", result )                
       
   176                 }
       
   177             else
       
   178                 {
       
   179                 SetResult( KCapabilityCapabilitesNotFound );
       
   180                 SetState( ECapabilityQueryCompleted );
       
   181                 }
       
   182             break;
       
   183             }
       
   184         case  KMUSAVASIPUnsupportedURIScheme:
       
   185         MUS_LOG( "mus: [MUSAVA] Unsupported URI Schem" )
       
   186             SetState( ECapabilityQueryCompleted );
       
   187             break;
       
   188         case KMUSAVASIPNotFound:
       
   189         case KMUSAVASIPTimeout:
       
   190         case KMUSAVASIPTemporarilyUnavailable:
       
   191             {
       
   192             DoRetryL();
       
   193             break;
       
   194             }
       
   195         default:
       
   196             {
       
   197             MUS_LOG( "mus: [MUSAVA] => FAILED" )
       
   198             SetResult( KCapabilityCapabilitesNotFound );
       
   199             SetState( ECapabilityQueryCompleted );
       
   200             break;
       
   201             }
       
   202         }
       
   203     
       
   204     MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQuery::DoCompletedL" )
       
   205     }
       
   206 
       
   207 // --------------------------------------------------------------------------
       
   208 // CMusAvaCapabilityQuery::DoCompleted200OKL
       
   209 // --------------------------------------------------------------------------
       
   210 //
       
   211 void CMusAvaCapabilityQuery::DoCompleted200OKL( 
       
   212 //                        const CSIPResponseElements& aResponse )
       
   213                                     const CSIPClientTransaction& aResponse )
       
   214     {
       
   215     SetState( ECapabilityQueryCompleted );
       
   216 
       
   217     // check if P-Asserted-Identity header exists
       
   218     _LIT8( KHeader,"P-Asserted-Identity" );
       
   219     RStringF p = SIPStrings::Pool().OpenFStringL( KHeader() );
       
   220     CleanupClosePushL( p );
       
   221 	
       
   222     TInt count = MusAvaCapabilityContext::HeaderCount( p, 
       
   223                     aResponse.ResponseElements()->MessageElements() );
       
   224             
       
   225     if ( count > 0 )
       
   226         {
       
   227         TUint index = 0;
       
   228         const CSIPHeaderBase* pAssertedId =  MusAvaCapabilityContext::Header(
       
   229                         p, 
       
   230                         aResponse.ResponseElements()->MessageElements(), 
       
   231                         index );
       
   232                         
       
   233         if ( pAssertedId )
       
   234             { // get SIP uri
       
   235             HBufC8* value = pAssertedId->ToTextValueLC();
       
   236             CSIPAddress* address = CSIPAddress::DecodeL( *value );
       
   237             CleanupStack::PushL( address );
       
   238                  
       
   239             const TDesC8& uriInPAssertedId = address->Uri8().Uri().UriDes();
       
   240         	if ( uriInPAssertedId.Length() > 0 )
       
   241     	        {
       
   242     		    HBufC* uri = EscapeUtils::ConvertToUnicodeFromUtf8L( 
       
   243     		                uriInPAssertedId );
       
   244         		CleanupStack::PushL( uri );   
       
   245         		Capability().Exchange().QueryObserver().
       
   246         		CapabilitiesResolvedL( *uri );
       
   247         		CleanupStack::PopAndDestroy( uri );
       
   248         		}
       
   249             CleanupStack::PopAndDestroy( 2 ); //address, value
       
   250             }
       
   251         }
       
   252     CleanupStack::PopAndDestroy( 1 ); //p
       
   253     
       
   254     const CSIPContentTypeHeader* contentTypeHeader = NULL;
       
   255         
       
   256     const CSIPResponseElements* response = aResponse.ResponseElements();
       
   257 
       
   258     contentTypeHeader = response->MessageElements().ContentType();
       
   259     
       
   260     if ( contentTypeHeader &&
       
   261          contentTypeHeader->
       
   262          MediaType().Compare( KMUSAVASIPMediaTypeApplication ) == 0 &&
       
   263          contentTypeHeader->
       
   264          MediaSubtype().Compare( KMUSAVASIPMediaSubTypeSDP ) == 0 )
       
   265         {
       
   266         CSdpDocument* sdp = 
       
   267             CSdpDocument::DecodeL( response->MessageElements().Content() );
       
   268         CleanupStack::PushL( sdp );
       
   269         
       
   270         TBool codec = ValidateAndStoreCodecsL( *sdp );
       
   271         TBool attributes = ValidateAttributesL( *sdp );
       
   272         TBool featureTag = ValidateContactL( aResponse );
       
   273         TBool operatorVariant = 
       
   274             MultimediaSharingSettings::OperatorVariantSettingL() ==
       
   275             MusSettingsKeys::EOperatorSpecific;
       
   276        
       
   277         if ( ( codec && attributes && featureTag  ) ||
       
   278             ( codec && !operatorVariant && featureTag ) )
       
   279         
       
   280             {
       
   281             MUS_LOG( "mus: [MUSAVA] => OK" )
       
   282             SetResult( KCapabilityCapabilitesReady );
       
   283             }
       
   284         
       
   285         else
       
   286             {
       
   287             MUS_LOG( "mus: [MUSAVA] => FAILED due SDP validation" )
       
   288             SetResult( KCapabilityCapabilitesNotFound );
       
   289             }
       
   290         
       
   291         CleanupStack::PopAndDestroy( sdp );
       
   292         
       
   293         }
       
   294     else
       
   295         {
       
   296         MUS_LOG( "mus: [MUSAVA] => FAILED due wrong content type" )
       
   297         SetResult( KCapabilityCapabilitesNotFound );
       
   298         }
       
   299     }
       
   300 
       
   301 // --------------------------------------------------------------------------
       
   302 // CMusAvaCapabilityQuery::ValidateCodecL
       
   303 // --------------------------------------------------------------------------
       
   304 //
       
   305 TBool CMusAvaCapabilityQuery::ValidateAndStoreCodecsL( CSdpDocument& aSDP )
       
   306     {
       
   307     MUS_LOG("mus: [MUSAVA]  -> CMusAvaCapabilityQuery::ValidateAndStoreCodecsL" )
       
   308 
       
   309     TBool valid = EFalse;
       
   310     
       
   311     CDesCArrayFlat* codecs = CMusAvaCapability::ResolveCodecsL( aSDP );
       
   312     CleanupStack::PushL( codecs );
       
   313     
       
   314     Capability().Exchange().QueryObserver().VideoCodecsResolvedL( *codecs );
       
   315     MUS_LOG1("mus: [MUSAVA]  -> codecs count = %d", codecs->MdcaCount() )
       
   316 
       
   317     if ( codecs->MdcaCount() > 0 )
       
   318         {
       
   319         valid = ETrue;
       
   320         }
       
   321 
       
   322     codecs->Reset();
       
   323     CleanupStack::PopAndDestroy( codecs );
       
   324     
       
   325     MUS_LOG("mus: [MUSAVA]  <- CMusAvaCapabilityQuery::ValidateAndStoreCodecsL" )
       
   326     return valid;
       
   327     }
       
   328 
       
   329 // --------------------------------------------------------------------------
       
   330 // CMusAvaCapabilityQuery::ValidateAttributesL
       
   331 // --------------------------------------------------------------------------
       
   332 //
       
   333 TBool CMusAvaCapabilityQuery::ValidateAttributesL( CSdpDocument& aSDP )
       
   334     {
       
   335     TBool valid = EFalse;
       
   336         
       
   337     const CSdpAttributeField* application = NULL;
       
   338     const CSdpAttributeField* type = NULL;
       
   339     RStringF attrTypeName = MusAvaCapabilityContext::SDPStringL( 
       
   340                                         KCapabilitySDPAttributeNameType );
       
   341     CleanupClosePushL( attrTypeName );
       
   342     
       
   343     // "a=application:comgsma.rts"
       
   344     application = CMusAvaCapability::Attribute( 
       
   345             MusAvaCapabilityContext::SDPStringL( 
       
   346                 SdpCodecStringConstants::EMediaApplication ),
       
   347             aSDP );
       
   348 
       
   349     // "a=type:videolive"
       
   350     type = CMusAvaCapability::Attribute( attrTypeName, aSDP );
       
   351     CleanupStack::PopAndDestroy();//attrTypeName
       
   352     
       
   353     if ( MultimediaSharingSettings::OperatorVariantSettingL() ==
       
   354                 MusSettingsKeys::EOperatorSpecific )
       
   355         {
       
   356         valid = application &&
       
   357             application->Value().Compare( KCapabilitySwisApplication ) == 0 &&
       
   358             type &&
       
   359             type->Value().Compare( KCapabilitySDPAttributeType ) == 0;
       
   360         }
       
   361     else
       
   362         {
       
   363         valid = ( application &&
       
   364             application->Value().Compare( KCapabilitySwisApplication ) == 0 ) ||
       
   365             ( type &&
       
   366             type->Value().Compare( KCapabilitySDPAttributeType ) == 0 ) ;
       
   367         
       
   368         }
       
   369     
       
   370     return valid;        
       
   371     }
       
   372 
       
   373 // --------------------------------------------------------------------------
       
   374 // CMusAvaCapabilityQuery::ValidateContactL
       
   375 // --------------------------------------------------------------------------
       
   376 //
       
   377 TBool CMusAvaCapabilityQuery::ValidateContactL( 
       
   378                                     const CSIPClientTransaction& aResponse )
       
   379     {
       
   380     TBool valid = EFalse;
       
   381     RStringF falseParam = MusAvaCapabilityContext::SIPStringL( 
       
   382                                                     KMUSAVASIPParamFalse );
       
   383     CleanupClosePushL( falseParam );
       
   384 
       
   385     const CSIPContactHeader* contact = 
       
   386         MusAvaCapabilityContext::ContactHeaderL( aResponse );
       
   387                                              
       
   388     if ( !contact )
       
   389         {
       
   390         MUS_LOG( "STCE: => FAILED due lack of contact header" )
       
   391         }
       
   392     else
       
   393         {
       
   394         if ( contact->HasParam( Capability().Feature() ) && 
       
   395             !contact->HasParam( falseParam ) )
       
   396             {
       
   397             valid = ETrue;
       
   398             }
       
   399         else
       
   400             {
       
   401             MUS_LOG( "STCE: => FAILED due wrong contact header" )
       
   402             }        
       
   403         }
       
   404     CleanupStack::PopAndDestroy();//falseParam
       
   405     
       
   406     return valid;
       
   407     }
       
   408     
       
   409 // --------------------------------------------------------------------------
       
   410 // CMusAvaCapabilityQuery::DoRetryL
       
   411 // --------------------------------------------------------------------------
       
   412 //
       
   413 void CMusAvaCapabilityQuery::DoRetryL()
       
   414     {
       
   415 
       
   416     if ( !iTimer )
       
   417         {
       
   418         MUS_LOG( "mus: [MUSAVA] => RE-TRYING" )
       
   419         
       
   420         iTimer = CMusAvaCapabilityTimer::NewL( *this );
       
   421         iTimer->After( KCapabilityTimervalue );
       
   422         Retrying() = ETrue;
       
   423         SetResult( KCapabilityQueryNotReady );
       
   424         SetState( ECapabilityQueryCreated );
       
   425         }
       
   426     else
       
   427         {
       
   428         MUS_LOG( "mus: [MUSAVA] => FAILED due failing retry" )
       
   429         Retrying() = EFalse;
       
   430         SetResult( KCapabilityCapabilitesNotFound );
       
   431         SetState( ECapabilityQueryCompleted );
       
   432         delete iTimer;
       
   433         iTimer = NULL;
       
   434         }
       
   435     }
       
   436 
       
   437 // --------------------------------------------------------------------------
       
   438 // CMusAvaCapabilityQuery::OnExpired
       
   439 // --------------------------------------------------------------------------
       
   440 //
       
   441 void CMusAvaCapabilityQuery::OnExpiredL( TInt /*aStatus*/ )
       
   442     {
       
   443     Retrying() = EFalse;
       
   444         
       
   445     ExecuteL();
       
   446     }
       
   447 
       
   448 // --------------------------------------------------------------------------
       
   449 // CMusAvaCapabilityQuery::Retrying
       
   450 // --------------------------------------------------------------------------
       
   451 //
       
   452 TBool& CMusAvaCapabilityQuery::Retrying()
       
   453     {
       
   454     return iRetrying;
       
   455     }