--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipAcceptContactStrategy.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,259 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name : CSipAcceptContactStrategy.cpp
+// Part of : SIP Client Resolver
+// Version : 1.0
+//
+
+
+
+#include "CSipAcceptContactStrategy.h"
+#include "MSipClients.h"
+#include "MSipClient.h"
+#include "sipresponse.h"
+#include "siprequest.h"
+#include "sipacceptcontactheader.h"
+#include "CSIPFeatureSet.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "TSIPClientScore.h"
+#include "SIPCRLogs.h"
+
+const TUint K480ResponseCode = 480;
+
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::NewL
+// ----------------------------------------------------------------------------
+//
+CSipAcceptContactStrategy* CSipAcceptContactStrategy::NewL(
+ MSipClients& aSipClients,
+ CSipHeaderStrategyBase* aNextStrategy,
+ CSipHeaderStrategyBase* aNextStrategy2 )
+ {
+ CSipAcceptContactStrategy* self =
+ CSipAcceptContactStrategy::NewLC( aSipClients,
+ aNextStrategy,
+ aNextStrategy2 );
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::NewLC
+// ----------------------------------------------------------------------------
+//
+CSipAcceptContactStrategy* CSipAcceptContactStrategy::NewLC(
+ MSipClients& aSipClients,
+ CSipHeaderStrategyBase* aNextStrategy,
+ CSipHeaderStrategyBase* aNextStrategy2 )
+ {
+ CSipAcceptContactStrategy* self =
+ new(ELeave)CSipAcceptContactStrategy( aSipClients,
+ aNextStrategy,
+ aNextStrategy2 );
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::CSipAcceptContactStrategy
+// ----------------------------------------------------------------------------
+//
+CSipAcceptContactStrategy::CSipAcceptContactStrategy(
+ MSipClients& aSipClients,
+ CSipHeaderStrategyBase* aNextStrategy,
+ CSipHeaderStrategyBase* aNextStrategy2 )
+ : CSipHeaderStrategyBase( aSipClients,aNextStrategy,aNextStrategy2 )
+ {
+ iAcceptContactHeaderName =
+ SIPStrings::StringF(SipStrConsts::EAcceptContactHeader);
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::~CSipAcceptContactStrategy
+// ----------------------------------------------------------------------------
+//
+CSipAcceptContactStrategy::~CSipAcceptContactStrategy ()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::ApplyL
+// ----------------------------------------------------------------------------
+//
+CSIPResponse* CSipAcceptContactStrategy::ApplyL(
+ CSIPRequest& aRequest,
+ RArray<TUid>& aUids,
+ TBool& aContinueSearch,
+ CSIPClientResolver2& aClientResolver2 )
+ {
+ SIP_CR_LOG("CSipAcceptContactStrategy::ApplyL")
+ CSIPResponse* response = NULL;
+ // The strategy is applied only for requests that contain Accept-Contact
+ if (aRequest.HasHeader(iAcceptContactHeaderName))
+ {
+ RArray<TSIPClientScore> scores(1);
+ CleanupClosePushL(scores);
+ RPointerArray<CSIPFeatureSet> requestFeatureSets =
+ CreateFeatureSetsL(aRequest);
+ TCleanupItem cleanupItem(DestroyFeatureSets,&requestFeatureSets);
+ CleanupStack::PushL(cleanupItem);
+ for (TInt i=0; i < aUids.Count(); i++)
+ {
+ TUid uid(aUids[i]);
+ MSipClient* client = iSipClients.GetByUID(uid);
+ if (client)
+ {
+ TInt score = CalculateScore(*client,requestFeatureSets);
+ if (score > 0)
+ {
+ TSIPClientScore clientScore(score,uid);
+ // The score is used as a key
+ scores.InsertInSignedKeyOrderAllowRepeatsL(clientScore);
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(1); // cleanupItem
+ TInt clientCount = scores.Count();
+ aUids.Reset(); // empties the array
+ if (clientCount > 0)
+ {
+ // The scores are in increasing order.
+ // The last is the best match. Reverse the order.
+ for (TInt i=scores.Count()-1; i>=0; i--)
+ {
+ // In the resulting array the first is the best match
+ aUids.AppendL(scores[i].iUid);
+ }
+ if (iNextStrategy && clientCount > 1)
+ {
+ // Apply the next strategy only if
+ // there are still more than one matching clients.
+ response = iNextStrategy->ApplyL(aRequest,aUids,
+ aContinueSearch,
+ aClientResolver2);
+ }
+ }
+ else
+ {
+ if ( iNextStrategy2 )
+ {
+ response = iNextStrategy2->ApplyL(aRequest,aUids,
+ aContinueSearch,
+ aClientResolver2);
+ }
+ else
+ {
+ response = CreateResponseL();
+ }
+
+ }
+ CleanupStack::PopAndDestroy(1); // scores
+ }
+ else
+ {
+ if (iNextStrategy)
+ {
+ response = iNextStrategy->ApplyL(aRequest,aUids,aContinueSearch,
+ aClientResolver2);
+ }
+ }
+
+ return response;
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::CreateResponseL
+// ----------------------------------------------------------------------------
+//
+CSIPResponse* CSipAcceptContactStrategy::CreateResponseL()
+ {
+ return CSIPResponse::NewL(K480ResponseCode,
+ SIPStrings::StringF(SipStrConsts::EPhraseTemporarilyNotAvailable));
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::CompareHeaders
+// ----------------------------------------------------------------------------
+//
+TBool CSipAcceptContactStrategy::CompareHeaders(
+ CSIPRequest& /*aRequest*/,
+ MSipClient& /*aClient*/)
+ {
+ // Not implemented for this sub-class
+ return EFalse;
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::CreateFeatureSetsL
+// ----------------------------------------------------------------------------
+//
+RPointerArray<CSIPFeatureSet> CSipAcceptContactStrategy::CreateFeatureSetsL(
+ CSIPRequest& aRequest)
+ {
+ RPointerArray<CSIPFeatureSet> featureSets;
+ TCleanupItem cleanupItem(DestroyFeatureSets,&featureSets);
+ CleanupStack::PushL(cleanupItem);
+ TSglQueIter<CSIPHeaderBase> iter =
+ aRequest.Headers(iAcceptContactHeaderName);
+ while (iter)
+ {
+ CSIPHeaderBase* tmp = iter++;
+ CSIPAcceptContactHeader* acceptContact =
+ static_cast<CSIPAcceptContactHeader*>(tmp);
+ CSIPFeatureSet* featureSet = CSIPFeatureSet::NewLC(*acceptContact);
+ featureSets.AppendL(featureSet);
+ CleanupStack::Pop(featureSet);
+ }
+ CleanupStack::Pop(1); // cleanupItem
+ return featureSets;
+ }
+
+// ----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::CalculateScore
+// ----------------------------------------------------------------------------
+//
+TInt CSipAcceptContactStrategy::CalculateScore(
+ MSipClient& aClient,
+ const RPointerArray<CSIPFeatureSet>& aRequestFeatureSets) const
+ {
+ TInt score = 0;
+ CSIPFeatureSet& clientFeatureSet = aClient.SIPFeatureSet();
+ for (TInt i = 0; i < aRequestFeatureSets.Count(); i++)
+ {
+ CSIPFeatureSet& requestFeatureSet = *aRequestFeatureSets[i];
+ TInt tmp = clientFeatureSet.CalculateScore(requestFeatureSet);
+ if (tmp == 0 && requestFeatureSet.Require())
+ {
+ return 0;
+ }
+ score += tmp;
+ }
+ return score;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipAcceptContactStrategy::DestroyFeatureSets
+// -----------------------------------------------------------------------------
+//
+void CSipAcceptContactStrategy::DestroyFeatureSets(TAny* aFeatureSets)
+ {
+ RPointerArray<CSIPFeatureSet>* featureSets =
+ reinterpret_cast<RPointerArray<CSIPFeatureSet>*>(aFeatureSets);
+ if (featureSets)
+ {
+ featureSets->ResetAndDestroy();
+ }
+ }