realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipLaunchingStrategies.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSipLaunchingStrategies.cpp
       
    15 // Part of       : SIP Client Resolver
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "CSipLaunchingStrategies.h"
       
    22 #include "sdpcodecstringconstants.h"
       
    23 #include "MSipClients.h"
       
    24 #include "MSipClient.h"
       
    25 #include "CSipAcceptContactStrategy2.h"
       
    26 #include "CSipAcceptContactStrategy.h"
       
    27 #include "CSipAllowEventsStrategy2.h"
       
    28 #include "CSipAllowEventsStrategy.h"
       
    29 #include "CSipRequestStrategy.h"
       
    30 #include "CSipContentTypeStrategy.h"
       
    31 #include "CSdpMLineNameStrategy.h"
       
    32 #include "CSdpMLineMediaStrategy.h"
       
    33 #include "CSdpMLineTransportStrategy.h"
       
    34 #include "CSdpRtpmapStrategy.h"
       
    35 #include "CSdpMediaAttributeStrategy.h"
       
    36 #include "CSIPOptionsHandler.h" 
       
    37 #include "sipresponse.h"
       
    38 #include "siprequest.h"
       
    39 #include "sipcontenttypeheader.h"
       
    40 #include "siperr.h"
       
    41 #include "sipstrings.h"
       
    42 #include "sipstrconsts.h"
       
    43 #include "sdpdocument.h"
       
    44 #include "SIPCRLogs.h"
       
    45 #include "CSIPClientResolver2.h"
       
    46 #include "sdpmediafield.h"
       
    47 
       
    48 const TUint KResponse400 = 400;
       
    49 const TUint KResponse501 = 501;
       
    50 
       
    51 _LIT8(KSdp, "sdp");
       
    52 _LIT8(KApplication, "application");
       
    53 
       
    54 
       
    55 // ----------------------------------------------------------------------------
       
    56 // CSipLaunchingStrategies::NewL
       
    57 // ----------------------------------------------------------------------------
       
    58 //
       
    59 CSipLaunchingStrategies* CSipLaunchingStrategies::NewL(
       
    60     MSipClients& aSipClients)
       
    61 	{
       
    62 	CSipLaunchingStrategies* self = 
       
    63 	    new(ELeave)CSipLaunchingStrategies(aSipClients);
       
    64 	CleanupStack::PushL(self);
       
    65 	self->ConstructL();
       
    66 	CleanupStack::Pop(self);
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 // ----------------------------------------------------------------------------
       
    71 // CSipLaunchingStrategies::CSipLaunchingStrategies
       
    72 // ----------------------------------------------------------------------------
       
    73 //
       
    74 CSipLaunchingStrategies::CSipLaunchingStrategies(
       
    75     MSipClients& aSipClients)
       
    76     : iSipClients(aSipClients) 
       
    77 	{	
       
    78 	}
       
    79 
       
    80 // ----------------------------------------------------------------------------
       
    81 // CSipLaunchingStrategies::ConstructL
       
    82 // ----------------------------------------------------------------------------
       
    83 //
       
    84 void CSipLaunchingStrategies::ConstructL()
       
    85 	{
       
    86 	// SIP header strategies
       
    87 	CSipContentTypeStrategy* contentTypeStrategy = 
       
    88 		CSipContentTypeStrategy::NewLC( iSipClients,NULL );
       
    89 	iSipStrategies.AppendL( contentTypeStrategy );
       
    90 	CleanupStack::Pop( contentTypeStrategy );	
       
    91 	
       
    92 	CSipRequestStrategy* requestStrategy = 
       
    93 		CSipRequestStrategy::NewLC( iSipClients,NULL,contentTypeStrategy );
       
    94 	iSipStrategies.AppendL( requestStrategy );
       
    95 	CleanupStack::Pop( requestStrategy );	
       
    96 	
       
    97 	CSipAllowEventsStrategy* allowEventsStrategy = 
       
    98 		CSipAllowEventsStrategy::NewLC( iSipClients, 
       
    99 										requestStrategy, 
       
   100 										requestStrategy );
       
   101 	iSipStrategies.InsertL( allowEventsStrategy,0 );
       
   102 	CleanupStack::Pop( allowEventsStrategy );
       
   103 	
       
   104 	CSipAllowEventsStrategy2* allowEventsStrategy2 =
       
   105 		CSipAllowEventsStrategy2::NewLC( iSipClients,
       
   106 										 requestStrategy,
       
   107 										 allowEventsStrategy );
       
   108 	iSipStrategies.InsertL( allowEventsStrategy2,0 );
       
   109 	CleanupStack::Pop( allowEventsStrategy2 );
       
   110 		
       
   111 	CSipAcceptContactStrategy* acceptContactStrategy = 
       
   112 		CSipAcceptContactStrategy::NewLC( iSipClients,
       
   113 										  allowEventsStrategy,
       
   114 										  allowEventsStrategy2 );	
       
   115 	iSipStrategies.InsertL( acceptContactStrategy,0 );
       
   116 	CleanupStack::Pop( acceptContactStrategy );
       
   117 	
       
   118     CSipAcceptContactStrategy2* acceptContactStrategy2 =
       
   119     	CSipAcceptContactStrategy2::NewLC( iSipClients,
       
   120     									   allowEventsStrategy2,
       
   121     									   acceptContactStrategy );
       
   122     iSipStrategies.InsertL( acceptContactStrategy2,0 );
       
   123 	CleanupStack::Pop( acceptContactStrategy2 );
       
   124     
       
   125     // SDP strategies
       
   126 	CSdpMLineMediaStrategy* mlineMedia = 
       
   127 	    CSdpMLineMediaStrategy::NewLC(iSipClients);
       
   128 	iSdpStrategies.AppendL(mlineMedia);
       
   129 	CleanupStack::Pop(mlineMedia);
       
   130 
       
   131 	CSdpMLineTransportStrategy* mlineTransport = 
       
   132 	    CSdpMLineTransportStrategy::NewLC(iSipClients);
       
   133 	iSdpStrategies.AppendL(mlineTransport);
       
   134 	CleanupStack::Pop(mlineTransport);
       
   135 
       
   136 	CSdpRtpmapStrategy* rtpmap = 
       
   137 		CSdpRtpmapStrategy::NewLC(iSipClients);
       
   138 	iSdpStrategies.AppendL(rtpmap);
       
   139 	CleanupStack::Pop(rtpmap);
       
   140 
       
   141     CSdpMediaAttributeStrategy* mediaAttribute = 
       
   142 		CSdpMediaAttributeStrategy::NewLC(iSipClients);
       
   143     iSdpStrategies.AppendL(mediaAttribute);
       
   144 	CleanupStack::Pop(mediaAttribute);
       
   145 
       
   146 	CSdpMLineNameStrategy* mlineName = 
       
   147 		CSdpMLineNameStrategy::NewLC(iSipClients);
       
   148     iSdpStrategies.AppendL(mlineName);
       
   149 	CleanupStack::Pop(mlineName);
       
   150 	}
       
   151 
       
   152 // ----------------------------------------------------------------------------
       
   153 // CSipLaunchingStrategies::~CSipLaunchingStrategies
       
   154 // ----------------------------------------------------------------------------
       
   155 //
       
   156 CSipLaunchingStrategies::~CSipLaunchingStrategies()
       
   157 	{
       
   158 	iSipStrategies.ResetAndDestroy();
       
   159 	iSdpStrategies.ResetAndDestroy();
       
   160 	}
       
   161 
       
   162 // ----------------------------------------------------------------------------
       
   163 // CSipLaunchingStrategies::ApplyL
       
   164 // ----------------------------------------------------------------------------
       
   165 //
       
   166 CSIPResponse* CSipLaunchingStrategies::ApplyL(
       
   167     CSIPRequest& aRequest, 
       
   168     RArray<TUid>& aUids,
       
   169     CSIPClientResolver2& aClientResolver2 )
       
   170 	{
       
   171 	SIP_CR_LOG("CSipLaunchingStrategies::ApplyL")	
       
   172 	if (aRequest.Method() == SIPStrings::StringF(SipStrConsts::EOptions))
       
   173 	    {
       
   174 	    SIP_CR_LOG("CSipLaunchingStrategies::ApplyL EOptions")
       
   175         if (ClientForOptionsL(aRequest,aUids,aClientResolver2))
       
   176             {
       
   177             return NULL;
       
   178             }
       
   179 	    }
       
   180     CSIPResponse* response = CheckMethodL(aRequest,aUids,aClientResolver2);
       
   181     if (response)
       
   182         {
       
   183         SIP_CR_LOG("CSipLaunchingStrategies::ApplyL wrong method")
       
   184         return response;
       
   185         }
       
   186     
       
   187     // Apply SIP header strategies
       
   188     TBool continueSearch = EFalse;
       
   189     response = iSipStrategies[0]->ApplyL(aRequest,aUids,continueSearch,
       
   190     									aClientResolver2 );
       
   191     
       
   192     // Apply SDP strategies
       
   193 	if (!response && 
       
   194 	    continueSearch && 
       
   195 	    HasSDPContent(const_cast<CSIPRequest&>(aRequest)))
       
   196 		{
       
   197 	    CSdpDocument* sdpDocument = NULL;
       
   198 		TRAPD (err, sdpDocument = CSdpDocument::DecodeL(aRequest.Content()));
       
   199 		SIP_CR_INT_LOG("CSdpDocument::DecodeL completed with", err)
       
   200 		if (err != KErrNone)
       
   201 			{
       
   202 			if (err == KErrNoMemory)
       
   203 				{
       
   204 				User::Leave(err);
       
   205 				}
       
   206 			return CSIPResponse::NewL(KResponse400, 
       
   207 			    SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
       
   208 			}
       
   209 	    CleanupStack::PushL(sdpDocument);			
       
   210 		if (!sdpDocument->IsValid())
       
   211 		    {
       
   212 		    response = CSIPResponse::NewL(KResponse400, 
       
   213 			    SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
       
   214 		    }
       
   215 		else
       
   216 		    {
       
   217 		    for (TInt j=0; j < iSdpStrategies.Count() && !response; j++)
       
   218 			    {
       
   219 			    response = iSdpStrategies[j]->ApplyL(*sdpDocument,aUids);
       
   220 			    }		    
       
   221 		    }
       
   222 	    CleanupStack::PopAndDestroy(sdpDocument);
       
   223 		}
       
   224 
       
   225 	return response;
       
   226 	}
       
   227 
       
   228 // ----------------------------------------------------------------------------
       
   229 // CSipLaunchingStrategies::CheckMethodL
       
   230 // ----------------------------------------------------------------------------
       
   231 //
       
   232 CSIPResponse* CSipLaunchingStrategies::CheckMethodL(
       
   233     CSIPRequest& aRequest,
       
   234     RArray<TUid>& aUids,
       
   235     CSIPClientResolver2& aClientResolver2)
       
   236     {
       
   237     CSIPResponse* response = NULL;
       
   238     RStringF method = aRequest.Method();
       
   239     
       
   240 	if (method == SIPStrings::StringF(SipStrConsts::EOptions))
       
   241 	    {
       
   242 	    response = CreateOptionsResponseL(aRequest,aUids,aClientResolver2);
       
   243 	    }
       
   244 	else if (method == SIPStrings::StringF(SipStrConsts::EPrack) ||
       
   245 	         method == SIPStrings::StringF(SipStrConsts::EBye) ||
       
   246 	         method == SIPStrings::StringF(SipStrConsts::EUpdate) ||
       
   247 	         method == SIPStrings::StringF(SipStrConsts::EAck))
       
   248 	    {
       
   249 	    response = 
       
   250 	        CSIPResponse::NewL(KResponse400,
       
   251 	            SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
       
   252 	    }
       
   253 	else if (method == SIPStrings::StringF(SipStrConsts::ERegister))
       
   254 	    {
       
   255         response = 
       
   256 	        CSIPResponse::NewL(KResponse501,
       
   257 	            SIPStrings::StringF(SipStrConsts::EPhraseNotImplemented)); 
       
   258 	    }
       
   259 	else
       
   260 	    {
       
   261 	    // NOP
       
   262 	    }
       
   263     
       
   264     return response;
       
   265     }
       
   266 
       
   267 // ----------------------------------------------------------------------------
       
   268 // CSipLaunchingStrategies::HasSDPContent
       
   269 // ----------------------------------------------------------------------------
       
   270 //
       
   271 TBool CSipLaunchingStrategies::HasSDPContent(CSIPRequest& aRequest)
       
   272 	{
       
   273 	CSIPHeaderBase* header = 
       
   274 	    aRequest.Header(
       
   275 	        SIPStrings::StringF(SipStrConsts::EContentTypeHeader),0);
       
   276 	
       
   277 	if (header)
       
   278 	    {
       
   279 	    CSIPContentTypeHeader* contentType =
       
   280 		    static_cast<CSIPContentTypeHeader*> (header);
       
   281 		
       
   282 	    if((contentType->MediaType()).CompareF(KApplication) != 0)
       
   283 		    {
       
   284 		    return EFalse;
       
   285 		    }
       
   286 	
       
   287 	    return (contentType->MediaSubtype().CompareF(KSdp) == 0);	    
       
   288 	    }
       
   289 
       
   290 	return EFalse;
       
   291 	}
       
   292 
       
   293 // ----------------------------------------------------------------------------
       
   294 // CSipLaunchingStrategies::CreateOptionsResponseL
       
   295 // ----------------------------------------------------------------------------
       
   296 //	
       
   297 CSIPResponse* CSipLaunchingStrategies::CreateOptionsResponseL(
       
   298     CSIPRequest& aRequest,
       
   299     RArray<TUid>& aUids,
       
   300     CSIPClientResolver2& aClientResolver2)
       
   301     {
       
   302     CSIPOptionsHandler* optionsHandler = CSIPOptionsHandler::NewLC(aRequest);
       
   303     
       
   304     for (TInt i=0; i < aUids.Count(); i++)
       
   305         {
       
   306         MSipClient* client = iSipClients.GetByUID(aUids[i]);
       
   307         if (client)
       
   308             {
       
   309             optionsHandler->AddClientDataL(client->SdpDocument());
       
   310             }
       
   311         }
       
   312         
       
   313     for (TInt i=0; i < aClientResolver2.Clients().Count(); i++)
       
   314         {
       
   315         CSIPResolvedClient2* client = aClientResolver2.Clients()[i];
       
   316         if ( client )
       
   317             {
       
   318             RPointerArray<CSdpMediaField> mediaFields;
       
   319             TRAPD( err,mediaFields = client->SupportedSdpMediasL() );
       
   320             if ( err == KErrNoMemory )
       
   321         		{
       
   322         		User::Leave( err );
       
   323         		}
       
   324             if ( !err )
       
   325             	{
       
   326             	CSipLaunchingStrategies::PushLC(&mediaFields);
       
   327             	optionsHandler->AddClientDataL(&mediaFields);
       
   328             	CleanupStack::Pop();//mediaFields
       
   329             	mediaFields.ResetAndDestroy();
       
   330             	}
       
   331             err = 0;
       
   332             }
       
   333         }   
       
   334         
       
   335     CSIPResponse* response = 
       
   336     				   optionsHandler->CreateResponseL( aUids,
       
   337 													    iSipClients,
       
   338     								  					aClientResolver2);
       
   339 
       
   340     CleanupStack::PopAndDestroy(optionsHandler);
       
   341     
       
   342     return response;
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CSipLaunchingStrategies::PushLC
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 void CSipLaunchingStrategies::PushLC(RPointerArray<CSdpMediaField>* aArray)
       
   350     {
       
   351 	CleanupStack::PushL(TCleanupItem(ResetAndDestroyArray,aArray));
       
   352     }
       
   353   
       
   354 // -----------------------------------------------------------------------------
       
   355 // CSipLaunchingStrategies::ResetAndDestroyArray
       
   356 // -----------------------------------------------------------------------------
       
   357 //
       
   358 void CSipLaunchingStrategies::ResetAndDestroyArray(TAny* anArray)
       
   359 	{
       
   360     RPointerArray<CSdpMediaField>* array =
       
   361         reinterpret_cast<RPointerArray<CSdpMediaField>*>(anArray);
       
   362     if (array)
       
   363         {
       
   364         array->ResetAndDestroy();
       
   365         }
       
   366 	}    
       
   367 
       
   368 // ----------------------------------------------------------------------------
       
   369 // CSipLaunchingStrategies::ClientForOptionsL
       
   370 // ----------------------------------------------------------------------------
       
   371 //    
       
   372 TBool CSipLaunchingStrategies::ClientForOptionsL(
       
   373     CSIPRequest& aRequest,
       
   374     RArray<TUid>& aUids,
       
   375     CSIPClientResolver2& aClientResolver2 )
       
   376     {
       
   377     TBool found = EFalse;
       
   378     if (aRequest.HasHeader(
       
   379             SIPStrings::StringF(SipStrConsts::EAcceptContactHeader)))
       
   380         {
       
   381         CSIPResponse* response = NULL;
       
   382         RArray<TUid> tmpUids;
       
   383 	    CleanupClosePushL(tmpUids);
       
   384         for (TInt i=0; i<aUids.Count(); i++)
       
   385 	        {
       
   386 	        tmpUids.AppendL(aUids[i]);
       
   387 	        }
       
   388         
       
   389         TBool secondGenerationClientsFound = 
       
   390             (aClientResolver2.Clients().Count() > 0);
       
   391             
       
   392 	    CSipAcceptContactStrategy* acceptContact = 
       
   393 	        CSipAcceptContactStrategy::NewLC( iSipClients,NULL,NULL );          
       
   394         
       
   395         TBool dummy = EFalse;
       
   396         
       
   397         if ( secondGenerationClientsFound )
       
   398         	{
       
   399     		CSipAcceptContactStrategy2* acceptContact2 =
       
   400     			CSipAcceptContactStrategy2::NewLC( iSipClients,
       
   401     									   		   NULL,
       
   402     									           acceptContact );
       
   403 	    	response = acceptContact2->ApplyL( aRequest,tmpUids,dummy,
       
   404 	    													aClientResolver2 );
       
   405 	    	CleanupStack::PopAndDestroy( acceptContact2 );        	
       
   406         	}
       
   407         else
       
   408         	{
       
   409             response = acceptContact->ApplyL( aRequest,tmpUids,dummy,
       
   410             												aClientResolver2 );
       
   411        		}
       
   412         CleanupStack::PopAndDestroy( acceptContact );
       
   413        	CleanupStack::PushL(response); 
       
   414 	    
       
   415 	    if (!response)
       
   416 	        {
       
   417 	        found = ETrue;
       
   418 	        aUids.Reset();
       
   419             // Add only the best match to the results.
       
   420             // The best match is the first item in the resulting array.
       
   421             if (tmpUids.Count() > 0)
       
   422                 {
       
   423                 aUids.AppendL(tmpUids[0]);
       
   424                 }  
       
   425 	        }
       
   426 	    delete response;
       
   427 		CleanupStack::Pop(); //response
       
   428 	    CleanupStack::PopAndDestroy(&tmpUids);     
       
   429         }
       
   430     return found;
       
   431     }