realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipAcceptContactStrategy.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2006-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          : CSipAcceptContactStrategy.cpp
       
    15 // Part of       : SIP Client Resolver
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "CSipAcceptContactStrategy.h"
       
    22 #include "MSipClients.h"
       
    23 #include "MSipClient.h"
       
    24 #include "sipresponse.h"
       
    25 #include "siprequest.h"
       
    26 #include "sipacceptcontactheader.h"
       
    27 #include "CSIPFeatureSet.h"
       
    28 #include "sipstrings.h"
       
    29 #include "sipstrconsts.h"
       
    30 #include "TSIPClientScore.h"
       
    31 #include "SIPCRLogs.h"
       
    32 	
       
    33 const TUint K480ResponseCode = 480;
       
    34 
       
    35 
       
    36 // ----------------------------------------------------------------------------
       
    37 // CSipAcceptContactStrategy::NewL
       
    38 // ----------------------------------------------------------------------------
       
    39 //
       
    40 CSipAcceptContactStrategy* CSipAcceptContactStrategy::NewL(
       
    41     MSipClients& aSipClients,
       
    42     CSipHeaderStrategyBase* aNextStrategy,
       
    43     CSipHeaderStrategyBase* aNextStrategy2 )
       
    44 	{
       
    45 	CSipAcceptContactStrategy* self = 
       
    46 		CSipAcceptContactStrategy::NewLC( aSipClients,
       
    47 										  aNextStrategy,
       
    48 										  aNextStrategy2 );
       
    49 	CleanupStack::Pop(self);
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 // ----------------------------------------------------------------------------
       
    54 // CSipAcceptContactStrategy::NewLC
       
    55 // ----------------------------------------------------------------------------
       
    56 //
       
    57 CSipAcceptContactStrategy* CSipAcceptContactStrategy::NewLC(
       
    58     MSipClients& aSipClients,
       
    59     CSipHeaderStrategyBase* aNextStrategy,
       
    60     CSipHeaderStrategyBase* aNextStrategy2 )
       
    61 	{
       
    62 	CSipAcceptContactStrategy* self = 
       
    63 		new(ELeave)CSipAcceptContactStrategy( aSipClients,
       
    64 											 aNextStrategy,
       
    65 											 aNextStrategy2 );
       
    66 	CleanupStack::PushL(self);
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 // ----------------------------------------------------------------------------
       
    71 // CSipAcceptContactStrategy::CSipAcceptContactStrategy
       
    72 // ----------------------------------------------------------------------------
       
    73 //
       
    74 CSipAcceptContactStrategy::CSipAcceptContactStrategy(
       
    75     MSipClients& aSipClients,
       
    76     CSipHeaderStrategyBase* aNextStrategy,
       
    77     CSipHeaderStrategyBase* aNextStrategy2 ) 
       
    78  : CSipHeaderStrategyBase( aSipClients,aNextStrategy,aNextStrategy2 )
       
    79 	{
       
    80 	iAcceptContactHeaderName = 
       
    81 	    SIPStrings::StringF(SipStrConsts::EAcceptContactHeader);
       
    82 	}
       
    83 
       
    84 // ----------------------------------------------------------------------------
       
    85 // CSipAcceptContactStrategy::~CSipAcceptContactStrategy
       
    86 // ----------------------------------------------------------------------------
       
    87 //
       
    88 CSipAcceptContactStrategy::~CSipAcceptContactStrategy ()
       
    89 	{
       
    90 	}
       
    91 
       
    92 // ----------------------------------------------------------------------------
       
    93 // CSipAcceptContactStrategy::ApplyL
       
    94 // ----------------------------------------------------------------------------
       
    95 //
       
    96 CSIPResponse* CSipAcceptContactStrategy::ApplyL(
       
    97     CSIPRequest& aRequest, 
       
    98     RArray<TUid>& aUids,
       
    99     TBool& aContinueSearch,
       
   100     CSIPClientResolver2& aClientResolver2 )
       
   101 	{
       
   102 	SIP_CR_LOG("CSipAcceptContactStrategy::ApplyL")
       
   103 	CSIPResponse* response = NULL;
       
   104 	// The strategy is applied only for requests that contain Accept-Contact
       
   105 	if (aRequest.HasHeader(iAcceptContactHeaderName))
       
   106         {
       
   107         RArray<TSIPClientScore> scores(1);
       
   108         CleanupClosePushL(scores);
       
   109         RPointerArray<CSIPFeatureSet> requestFeatureSets = 
       
   110             CreateFeatureSetsL(aRequest);
       
   111         TCleanupItem cleanupItem(DestroyFeatureSets,&requestFeatureSets);
       
   112 	    CleanupStack::PushL(cleanupItem);
       
   113 	    for (TInt i=0; i < aUids.Count(); i++)
       
   114 		    {
       
   115 		    TUid uid(aUids[i]);
       
   116 		    MSipClient* client = iSipClients.GetByUID(uid);
       
   117 		    if (client)
       
   118 			    {
       
   119 			    TInt score = CalculateScore(*client,requestFeatureSets);
       
   120 			    if (score > 0)
       
   121 			        {
       
   122 			        TSIPClientScore clientScore(score,uid);
       
   123 			        // The score is used as a key
       
   124 			        scores.InsertInSignedKeyOrderAllowRepeatsL(clientScore);
       
   125 			        }
       
   126 			    }	
       
   127 		    }
       
   128     	CleanupStack::PopAndDestroy(1); // cleanupItem
       
   129     	TInt clientCount = scores.Count();
       
   130     	aUids.Reset(); // empties the array
       
   131 	    if (clientCount > 0)
       
   132 	        {
       
   133 	        // The scores are in increasing order. 
       
   134 	        // The last is the best match. Reverse the order.
       
   135 	        for (TInt i=scores.Count()-1; i>=0; i--)
       
   136 	            {
       
   137 	            // In the resulting array the first is the best match
       
   138 	            aUids.AppendL(scores[i].iUid);
       
   139 	            } 
       
   140 	        if (iNextStrategy && clientCount > 1)
       
   141 	            {
       
   142 	            // Apply the next strategy only if 
       
   143 	            // there are still more than one matching clients.
       
   144 	            response = iNextStrategy->ApplyL(aRequest,aUids,
       
   145 	                                             aContinueSearch,
       
   146 	                                             aClientResolver2);
       
   147 	            }
       
   148 	        }
       
   149 	    else
       
   150 		    {
       
   151 		    if ( iNextStrategy2 )
       
   152 		    	{
       
   153 		    	response = iNextStrategy2->ApplyL(aRequest,aUids,
       
   154 		    									  aContinueSearch,
       
   155 		    									  aClientResolver2);
       
   156 		    	}
       
   157 		    else
       
   158 		    	{
       
   159 		    	response = CreateResponseL();
       
   160 		    	}
       
   161 		    
       
   162 		    }
       
   163 		CleanupStack::PopAndDestroy(1); // scores
       
   164         }
       
   165     else
       
   166         {
       
   167         if (iNextStrategy)
       
   168             {
       
   169 	        response = iNextStrategy->ApplyL(aRequest,aUids,aContinueSearch,
       
   170 	        												aClientResolver2);
       
   171 	        }
       
   172         }
       
   173 
       
   174     return response;
       
   175 	}
       
   176 
       
   177 // ----------------------------------------------------------------------------
       
   178 // CSipAcceptContactStrategy::CreateResponseL
       
   179 // ----------------------------------------------------------------------------
       
   180 //
       
   181 CSIPResponse* CSipAcceptContactStrategy::CreateResponseL()
       
   182     {
       
   183     return CSIPResponse::NewL(K480ResponseCode,
       
   184         SIPStrings::StringF(SipStrConsts::EPhraseTemporarilyNotAvailable));
       
   185     }
       
   186 
       
   187 // ----------------------------------------------------------------------------
       
   188 // CSipAcceptContactStrategy::CompareHeaders
       
   189 // ----------------------------------------------------------------------------
       
   190 //
       
   191 TBool CSipAcceptContactStrategy::CompareHeaders(
       
   192     CSIPRequest& /*aRequest*/,
       
   193     MSipClient& /*aClient*/)
       
   194 	{
       
   195 	// Not implemented for this sub-class
       
   196 	return EFalse;
       
   197 	}
       
   198 
       
   199 // ----------------------------------------------------------------------------
       
   200 // CSipAcceptContactStrategy::CreateFeatureSetsL
       
   201 // ----------------------------------------------------------------------------
       
   202 //
       
   203 RPointerArray<CSIPFeatureSet> CSipAcceptContactStrategy::CreateFeatureSetsL(
       
   204     CSIPRequest& aRequest)
       
   205     {
       
   206     RPointerArray<CSIPFeatureSet> featureSets;
       
   207     TCleanupItem cleanupItem(DestroyFeatureSets,&featureSets);
       
   208 	CleanupStack::PushL(cleanupItem);
       
   209 	TSglQueIter<CSIPHeaderBase> iter = 
       
   210 	    aRequest.Headers(iAcceptContactHeaderName);	
       
   211 	while (iter)
       
   212 		{
       
   213 		CSIPHeaderBase* tmp = iter++;
       
   214 		CSIPAcceptContactHeader* acceptContact = 
       
   215 		    static_cast<CSIPAcceptContactHeader*>(tmp);
       
   216 		CSIPFeatureSet* featureSet = CSIPFeatureSet::NewLC(*acceptContact);
       
   217 		featureSets.AppendL(featureSet);
       
   218 		CleanupStack::Pop(featureSet);
       
   219 		}	
       
   220 	CleanupStack::Pop(1); // cleanupItem 
       
   221     return featureSets;
       
   222     }
       
   223 
       
   224 // ----------------------------------------------------------------------------
       
   225 // CSipAcceptContactStrategy::CalculateScore
       
   226 // ----------------------------------------------------------------------------
       
   227 //	
       
   228 TInt CSipAcceptContactStrategy::CalculateScore(
       
   229     MSipClient& aClient,
       
   230     const RPointerArray<CSIPFeatureSet>& aRequestFeatureSets) const
       
   231     {
       
   232     TInt score = 0;
       
   233     CSIPFeatureSet& clientFeatureSet = aClient.SIPFeatureSet();
       
   234     for (TInt i = 0; i < aRequestFeatureSets.Count(); i++)
       
   235         {
       
   236         CSIPFeatureSet& requestFeatureSet = *aRequestFeatureSets[i];
       
   237         TInt tmp = clientFeatureSet.CalculateScore(requestFeatureSet);
       
   238         if (tmp == 0 && requestFeatureSet.Require())
       
   239             {
       
   240             return 0;
       
   241             }
       
   242         score += tmp;
       
   243         }
       
   244     return score;
       
   245     }
       
   246     
       
   247 // -----------------------------------------------------------------------------
       
   248 // CSipAcceptContactStrategy::DestroyFeatureSets
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 void CSipAcceptContactStrategy::DestroyFeatureSets(TAny* aFeatureSets)
       
   252 	{
       
   253     RPointerArray<CSIPFeatureSet>* featureSets =
       
   254         reinterpret_cast<RPointerArray<CSIPFeatureSet>*>(aFeatureSets);
       
   255     if (featureSets)
       
   256         {
       
   257         featureSets->ResetAndDestroy();
       
   258         }
       
   259 	}