realtimenetprots/sipfw/SIP/Registration/src/CSIPRegistrationBindingStore.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Registration/src/CSIPRegistrationBindingStore.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,584 @@
+// Copyright (c) 2005-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          : CSIPRegistrationBindingStore.cpp
+// Part of       : Registration
+// Version       : SIP/4.0 
+//
+
+
+
+#include "CSIPRegistrationBinding.h"
+#include "CSIPRegistrationRefreshBinding.h"
+#include "CSIPRegistrationBindingStore.h"
+#include "CSIPResponseUtility.h"
+#include "CSIPRegistrarStore.h"
+#include "sipcontactheader.h"
+#include "sipaddress.h"
+#include "uricontainer.h"
+#include "sipuri.h"
+#include "siphostport.h"
+#include "siprouteheader.h"
+#include "siptoheader.h"
+#include "DeleteMgr.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "SipLogs.h"
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingStore* CSIPRegistrationBindingStore::NewL(
+	CSIPRegistrarStore& aRegistrarStore)
+	{
+	CSIPRegistrationBindingStore* self = 
+		CSIPRegistrationBindingStore::NewLC(aRegistrarStore);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingStore* CSIPRegistrationBindingStore::NewLC(
+	CSIPRegistrarStore& aRegistrarStore)
+	{
+    CSIPRegistrationBindingStore* self = 
+		new (ELeave) CSIPRegistrationBindingStore(aRegistrarStore);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::CSIPRegistrationBindingStore
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingStore::CSIPRegistrationBindingStore(
+	CSIPRegistrarStore& aRegistrarStore)
+
+  : iRegistrarStore     (aRegistrarStore),
+    iNextRegistrationId (KMinRegistrationId)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationBindingStore::ConstructL()
+	{
+	iDeleteMgr = CDeleteMgr::NewL();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::~CSIPRegistrationBindingStore
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingStore::~CSIPRegistrationBindingStore()
+	{
+	iBindings.ResetAndDestroy();
+	delete iDeleteMgr;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::FindBinding
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingBase* CSIPRegistrationBindingStore::FindBinding(
+	const MRegistrationOwner& aRegistrationOwner,
+	CSIPRequest&              aSIPRequest)
+	{ 
+	CSIPRegistrationBindingBase* returnValue = NULL;
+	
+	for (TInt i=iBindings.Count()-1; (i>=0 && !returnValue); i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+
+		if (binding->CompareWithRegisterRequest(
+			aRegistrationOwner, aSIPRequest))
+			{
+			returnValue = binding; 
+			}
+		}
+
+	return returnValue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::FindBinding
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationBindingBase* CSIPRegistrationBindingStore::FindBinding(
+	const TRegistrationId& aRegistrationId,
+	const MRegistrationOwner* aOwner)
+	{
+	CSIPRegistrationBindingBase* returnValue = NULL;
+
+	if (aRegistrationId == KEmptyRegistrationId)
+		{
+		return returnValue;
+		}
+
+	for (TInt i=iBindings.Count()-1; (i>=0 && !returnValue); i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		 
+		if (binding->RegistrationId() == aRegistrationId &&
+		    (!aOwner || binding->Owner() == aOwner))
+			{
+			returnValue = binding;
+			}
+		}
+
+	return returnValue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::FindBindingForTransaction
+// -----------------------------------------------------------------------------
+//
+const CSIPRegistrationBindingBase* 
+CSIPRegistrationBindingStore::FindBindingForTransaction(
+    const TTransactionId& aTransactionId)
+    {
+	for (TInt i=0; i < iBindings.Count(); i++)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		if (binding->HasTransaction(aTransactionId))
+			{
+			return binding;
+			}
+		}
+	return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::FindContactByFromL
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::FindContactByFromL(
+	const CSIPFromToHeaderBase* aFromToHeader,
+	CSIPContactHeader&          aContact)
+	{
+	TBool found = EFalse;
+
+	for (TInt i=iBindings.Count()-1; (i>=0 && !found); i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		found = binding->FindContactByFromL(aFromToHeader, aContact);
+		}
+	
+	return found;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RemoveBinding
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationBindingStore::RemoveBinding (
+	const CSIPRegistrationBindingBase* aBinding)
+	{
+	TInt err   = KErrNotFound;
+	TInt index = KErrNotFound;
+
+	index  = iBindings.Find(aBinding);
+
+	// binding found 
+	if (index  >= 0)
+		{
+		err = iDeleteMgr->AddDeleteRequest(aBinding);
+
+		if (err == KErrNone)
+			{
+			iBindings.Remove(index);
+			}
+		}
+
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RemoveBindingByIAPId
+// remove bindings, which contain same IAPId as the parameter
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationBindingStore::RemoveBindingByIAPId (
+	const TUint32 aIapId)
+	{
+	for (TInt i=iBindings.Count()-1; i>=0; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		 
+		if (binding->IAPId() == aIapId)
+			{
+			iBindings.Remove(i);
+			delete binding;
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RemoveBinding
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationBindingStore::RemoveBinding (
+    const TRegistrationId& aRegistrationId,
+    const MRegistrationOwner* aOwner)
+    {
+    TInt returnValue = KErrNotFound;
+
+    CSIPRegistrationBindingBase* binding = FindBinding(aRegistrationId,aOwner);
+    if (binding)
+        {
+        TInt index = iBindings.Find(binding); 
+        if (index != KErrNotFound)
+            {
+            iBindings.Remove(index); 
+            delete binding;
+            binding = NULL;
+            returnValue = KErrNone;
+            }
+        }
+
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::ClearRegistrationOwner
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationBindingStore::ClearRegistrationOwner(
+	const MRegistrationOwner* aRegistrationOwner)
+	{
+	TInt err = KErrNotFound;
+
+	for (TInt i=iBindings.Count()-1; i>=0; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+
+		if (binding->Owner() == aRegistrationOwner)
+			{
+			iBindings.Remove(i);
+			delete binding;
+			binding = NULL;
+			err = KErrNone;
+			}
+		}
+
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RegistrarStore
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrarStore& CSIPRegistrationBindingStore::RegistrarStore()
+	{
+	return iRegistrarStore;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::NextRegistrationId
+// -----------------------------------------------------------------------------
+//
+TRegistrationId CSIPRegistrationBindingStore::NextRegistrationId()
+	{
+	TRegistrationId registrationId = iNextRegistrationId;
+
+    if (iNextRegistrationId == KMaxRegistrationId)
+		{
+		iNextRegistrationId = KMinRegistrationId;
+		}
+	else
+		{
+	    iNextRegistrationId++;
+		}
+
+	return registrationId;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::CheckRequestURI
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::CheckRequestURI(CURIContainer& aRequestUri)
+	{
+	TBool matchFound = EFalse;
+
+	for (TInt i=iBindings.Count()-1; i>=0 && !matchFound; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		CSIPURI* bindingUri = binding->Contact().SIPAddress()->URI().SIPURI();
+
+        // Check only the user part. 
+        // The host part may be have been changed 
+        // by the proxy/registrar due to presence of NAT.
+		if (aRequestUri.IsSIPURI() &&
+		    bindingUri &&
+		    bindingUri->IsSIPSURI() == aRequestUri.SIPURI()->IsSIPSURI() &&
+		    bindingUri->User().CompareF(aRequestUri.SIPURI()->User()) == 0)
+			{
+			matchFound = ETrue;
+			}
+		}
+
+	return matchFound;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::SetOutboundProxyL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegistrationBindingStore::SetOutboundProxyL (
+    const TRegistrationId& aRegistrationId,
+    CSIPRouteHeader* aOutboundProxy,
+    const MRegistrationOwner* aOwner)
+    {
+    CSIPRegistrationBindingBase* binding = FindBinding(aRegistrationId,aOwner);
+    if  (!binding)
+        {
+        User::Leave(KErrNotFound);
+        }
+    binding->SetOutboundProxyL(aOutboundProxy);
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::OutboundProxy
+// -----------------------------------------------------------------------------
+//
+const CSIPRouteHeader* CSIPRegistrationBindingStore::OutboundProxy(
+	TRegistrationId aRegistrationId)
+	{
+	CSIPRegistrationBindingBase* binding = FindBinding(aRegistrationId);
+
+    CSIPRouteHeader* proxy = NULL;
+
+    if (binding)
+        {
+        proxy = const_cast<CSIPRouteHeader*>(binding->OutboundProxy());
+        }
+        
+	return proxy;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::HasOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::HasOutboundProxy(
+	TRegistrationId aRegistrationId) 
+	{
+	TBool returnValue = EFalse; 
+
+	CSIPRegistrationBindingBase* binding = FindBinding(aRegistrationId);
+
+	if (binding && binding->HasOutboundProxy())
+		{
+		returnValue = ETrue;
+		}
+
+	return returnValue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::IsOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::IsOutboundProxy (const CURIContainer& aUri)
+    {
+    TBool isOutboundProxy = EFalse;
+
+	for (TInt i=iBindings.Count()-1; i>=0 && !isOutboundProxy; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+		const CSIPRouteHeader* proxy = binding->OutboundProxy();
+		if (binding->HasOutboundProxy() && 
+		    proxy->SIPAddress().URI().IsSIPURI() &&
+		    aUri.IsSIPURI())
+            {
+	    	const CSIPURI& sipuri = *aUri.SIPURI();
+	    	RStringF maddr = SIPStrings::StringF(SipStrConsts::EMaddr);
+
+	    	const TDesC8 *uriHost(NULL);
+	    	if (sipuri.HasParam(maddr))
+	    		{
+	    		uriHost = &sipuri.ParamValue(maddr).DesC();
+		   		}
+			else
+				{
+				uriHost = &sipuri.HostPort().Host();
+				}            
+            TPtrC8 proxyHost = 
+                proxy->SIPAddress().URI().SIPURI()->HostPort().Host();            
+            if (proxyHost.CompareF(*uriHost) == 0)
+                {
+                isOutboundProxy = ETrue;
+                }
+            }
+		}
+
+	return isOutboundProxy;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RemoveOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationBindingStore::RemoveOutboundProxy(
+	const TRegistrationId& aRegistrationId,
+	const MRegistrationOwner* aOwner)
+	{
+	TInt err = KErrNotFound;
+
+	if (aRegistrationId == KEmptyRegistrationId)
+		{
+		return err;
+		}
+
+	for (TInt i=iBindings.Count()-1; (i>=0 && err==KErrNotFound); i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+
+		if (binding->RegistrationId() == aRegistrationId &&
+		    binding->Owner() == aOwner)
+			{
+			err = binding->RemoveOutboundProxy();
+			}
+		}
+
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::CompareUri
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::CompareUri(const CURIContainer& aProxy, CURIContainer& aUri)
+	{
+    const TUint KDefaultSipPort 	  = 5060;
+    const TUint KDefaultSipPortForTLS = 5061;
+    
+	if(aProxy.SIPURI()->HostPort().Host() != aUri.SIPURI()->HostPort().Host())
+		/* Hosts dont match */
+		{
+		return FALSE;
+		}
+	else if(aProxy.SIPURI()->HostPort().HasPort() != aUri.SIPURI()->HostPort().HasPort())
+		/* If the port is KDefaultSipPort/KDefaultSipPortForTLS
+		 * then it is optional to mention the port in the URI
+		 * and the check can be ignored
+		 */
+		{
+		if(aProxy.SIPURI()->IsSIPSURI() &&
+				aProxy.SIPURI()->IsSIPSURI() == aUri.SIPURI()->IsSIPSURI())
+	        {
+	        if( aProxy.SIPURI()->HostPort().Port() != KDefaultSipPortForTLS &&
+	        		aUri.SIPURI()->HostPort().Port() != KDefaultSipPortForTLS)
+	        	{
+	        	return FALSE;
+	        	}
+	        }
+		else if( aProxy.SIPURI()->HostPort().Port() != KDefaultSipPort &&
+				aUri.SIPURI()->HostPort().Port() != KDefaultSipPort)
+			{
+	        return FALSE;
+	        }
+		}
+	else if(aProxy.SIPURI()->HostPort().HasPort() &&
+			aProxy.SIPURI()->HostPort().Port() != aUri.SIPURI()->HostPort().Port())
+		/* Ports dont match */
+		{
+		return FALSE;
+		}
+	return TRUE;
+ 	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::URIFailed
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegistrationBindingStore::URIFailed (CURIContainer& aUri)
+    {
+	for (TInt i=iBindings.Count()-1; i>=0; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+        const CSIPRouteHeader* proxy = binding->OutboundProxy();
+        if(proxy)
+        	{
+        	TBool uriMatch = CompareUri(proxy->SIPAddress().URI(), aUri);
+        	if (uriMatch &&
+        			!binding->RegisterPending())
+        	            {
+        	            // Remove binding only the registration is not pending,
+        	            // which means this failure was not related to a REGISTER request.
+        	            // If a REGISTER request fails, we will get a 
+        	            // TransactionEnded-callback from TU.
+        	            __SIP_LOG("CSIPRegistrationBindingStore::URIFailed")
+        				iBindings.Remove(i);
+        				binding->OutboundProxyFailed();
+        				delete binding;            
+        	            }
+        	}
+		}   
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::RegisterPendingToAOR
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationBindingStore::RegisterPendingToAOR (
+	const CURIContainer& aAOR)
+	{
+	TBool registerPending = EFalse;
+
+	for (TInt i=iBindings.Count()-1; i>=0 && !registerPending; i--)
+		{
+		CSIPRegistrationBindingBase* binding = iBindings[i];
+
+		if (binding->AOR().SIPAddress().URI() == aAOR &&
+		    binding->RegisterPending())
+			{
+			registerPending = ETrue;
+			}
+		}
+
+	return registerPending;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::AddBindingL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationBindingStore::AddBindingL(
+	CSIPRegistrationBindingBase* aBinding)
+	{
+	iBindings.AppendL(aBinding);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationBindingStore::DetachBinding
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationBindingStore::DetachBinding (
+	CSIPRegistrationBindingBase* aBinding)
+	{
+	TInt index = KErrNotFound;
+	index  = iBindings.Find(aBinding);
+	if (index != KErrNotFound)
+		{
+		iBindings.Remove(index);
+		}
+	}