--- /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);
+ }
+ }