diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipAcceptContactStrategy.cpp --- /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& 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 scores(1); + CleanupClosePushL(scores); + RPointerArray 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 CSipAcceptContactStrategy::CreateFeatureSetsL( + CSIPRequest& aRequest) + { + RPointerArray featureSets; + TCleanupItem cleanupItem(DestroyFeatureSets,&featureSets); + CleanupStack::PushL(cleanupItem); + TSglQueIter iter = + aRequest.Headers(iAcceptContactHeaderName); + while (iter) + { + CSIPHeaderBase* tmp = iter++; + CSIPAcceptContactHeader* acceptContact = + static_cast(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& 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* featureSets = + reinterpret_cast*>(aFeatureSets); + if (featureSets) + { + featureSets->ResetAndDestroy(); + } + }