--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Registration/src/CSIPRegistrationMgr.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,614 @@
+// 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 : CSIPRegistrationMgr.cpp
+// Part of : Registration
+// Version : SIP/4.0
+//
+
+
+
+
+#include "CSIPRegistrationMgr.h"
+#include "CSIPRegistrarStore.h"
+#include "CSIPRegistrar.h"
+#include "CSIPRegistrationBindingStore.h"
+#include "CSIPRegistrationBinding.h"
+#include "CSIPRegistrationRefreshBinding.h"
+#include "TSIPRegistrationUtility.h"
+#include "csipregistrationstate.h"
+#include "MRegistrationOwner.h"
+#include "MTransactionUser.h"
+#include "MSipRefreshMgr.h"
+#include "siprequest.h"
+#include "sipfromheader.h"
+#include "siptoheader.h"
+#include "sippassociateduriheader.h"
+#include "sipaddress.h"
+#include "sipcontactheader.h"
+#include "sipuri.h"
+#include "uricontainer.h"
+#include "siphostport.h"
+#include "siprouteheader.h"
+#include "SipLogs.h"
+#include "siperr.h"
+#include "SipAssert.h"
+#include "sipcodecerr.h"
+#include "TSIPTransportParams.h"
+
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationMgr* CSIPRegistrationMgr::NewL(MTransactionUser& aTU,
+ MSipRefreshMgr& aRefreshMgr,
+ MTimerManager& aTimerManager,
+ CSIPSec& aSIPSec,
+ MSigComp& aSigComp,
+ MSIPTransportMgr& aTransportMgr)
+ {
+ CSIPRegistrationMgr* self =
+ new (ELeave) CSIPRegistrationMgr(aTU, aRefreshMgr, aTimerManager,
+ aSIPSec, aSigComp, aTransportMgr);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::CSIPRegistrationMgr
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationMgr::CSIPRegistrationMgr(MTransactionUser& aTU,
+ MSipRefreshMgr& aRefreshMgr,
+ MTimerManager& aTimerManager,
+ CSIPSec& aSIPSec,
+ MSigComp& aSigComp,
+ MSIPTransportMgr& aTransportMgr)
+ : iTU (aTU),
+ iRefreshMgr (aRefreshMgr),
+ iTimerMgr (aTimerManager),
+ iSIPSec (aSIPSec),
+ iSigComp (aSigComp),
+ iTransportMgr (aTransportMgr)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::ConstructL()
+ {
+ //ask the local address from transaction user.
+ iRegistrarStore = CSIPRegistrarStore::NewL();
+ iBindingStore = CSIPRegistrationBindingStore::NewL(*iRegistrarStore);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::~CSIPRegistrationMgr
+// -----------------------------------------------------------------------------
+//
+CSIPRegistrationMgr::~CSIPRegistrationMgr()
+ {
+ delete iBindingStore;
+ delete iRegistrarStore;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::RegisterL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::RegisterL (TTransactionId& aTransactionId,
+ TRegistrationId& aRegistrationId,
+ CSIPRequest* aRequest,
+ CURIContainer& aRemoteTarget,
+ MRegistrationOwner* aRegistrationOwner,
+ MSIPSecUser& aSIPSecUser,
+ CSIPRouteHeader* aOutboundProxy,
+ TBool aRefresh,
+ TBool aSendWithExpires,
+ TBool aCacheOutboundProxyIP)
+ {
+ // panic if aRequest is 0 in debug mode. leaves in release mode.
+ __SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+ // panic if aRegistrationOwner is 0 in debug mode. leaves in release mode.
+ __SIP_ASSERT_LEAVE(aRegistrationOwner, KErrArgument);
+
+ __SIP_MESSAGE_LOG("Registration::RegisterL", *aRequest)
+
+ TUint32 iapId = aRegistrationOwner->TransportParams().IapId();
+ TSIPRegistrationUtility::CheckRegisterRequestL(
+ *aRequest,aOutboundProxy,iapId,iTU);
+
+ if (aOutboundProxy)
+ {
+ __ASSERT_ALWAYS(aOutboundProxy->SIPAddress().URI().IsSIPURI(),
+ User::Leave(KErrSipCodecURIScheme));
+ TSIPRegistrationUtility::CheckOutboundProxyCompParameterL(
+ *aOutboundProxy, iSigComp);
+ }
+
+ // check if there are pending bindings to same AOR (registrar)
+ if(iBindingStore->RegisterPendingToAOR(
+ aRequest->To()->SIPAddress().URI()))
+ {
+ User::Leave(KErrSIPRequestPending);
+ }
+
+ // find existing binding by comparing URI of To, Form and Contact
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(*aRegistrationOwner, *aRequest);
+
+ // leave if binding already exists
+ __ASSERT_ALWAYS (!binding, User::Leave (KErrAlreadyExists));
+
+ if (aRemoteTarget.IsSIPURI())
+ {
+ aRemoteTarget.SIPURI()->DeleteUserInfo(); // user and password
+ }
+
+ if (aRefresh) // create refresh binding
+ {
+ binding = CSIPRegistrationRefreshBinding::NewLC(
+ aRequest, iTU, iSigComp, iSIPSec, iRefreshMgr,
+ *iBindingStore, aRegistrationOwner, aSIPSecUser,
+ iTransportMgr, aRemoteTarget,aSendWithExpires,
+ aCacheOutboundProxyIP);
+ }
+ else // create non refresh binding
+ {
+ binding = CSIPRegistrationBinding::NewLC(
+ aRequest, iSigComp, iSIPSec, iTimerMgr, iTU,
+ *iBindingStore, aRegistrationOwner, aSIPSecUser,
+ iTransportMgr, aRemoteTarget,aSendWithExpires,
+ aCacheOutboundProxyIP);
+ }
+ TCleanupItem cleanupItem (DetachBinding, binding);
+ iBindingStore->AddBindingL(binding);
+ // if register fails, cleanupItem detach the binding from binding store.
+ CleanupStack::PushL(cleanupItem);
+ // send request
+ binding->CurrentState().RegisterL(aTransactionId, aRequest, aOutboundProxy);
+ CleanupStack::Pop(); // cleanupItem
+ CleanupStack::Pop(binding);
+ aRegistrationId = binding->RegistrationId();
+ binding->SetRequest(aRequest); // take ownership of request
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::UpdateRegistrationL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::UpdateRegistrationL (
+ const TRegistrationId& aRegistrationId,
+ TTransactionId& aTransactionId,
+ CSIPRequest* aRequest,
+ const MRegistrationOwner* aOwner)
+ {
+ __SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+
+ __SIP_MESSAGE_LOG("Registration::UpdateRegistrationL", *aRequest)
+
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId,aOwner);
+
+ // leave if binding doesn't exist
+ __ASSERT_ALWAYS (binding, User::Leave(KErrSIPInvalidRegistrationState));
+
+ TSIPRegistrationUtility::CheckUpdateRegisterRequestL(*aRequest, *binding);
+
+ // if UpdateL fails the binding must be detached from binding store
+ // and deleted. the cleanupItem detaches binding from binding store.
+ TCleanupItem cleanupItem(DetachBinding, binding);
+ CleanupStack::PushL(binding);
+ CleanupStack::PushL(cleanupItem);
+ // send request
+ binding->CurrentState().UpdateL(aTransactionId, aRequest);
+ CleanupStack::Pop(); // cleanupItem
+ CleanupStack::Pop(binding);
+ binding->SetRequest(aRequest); // take ownership of aRequest
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::UnRegisterL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::UnRegisterL (const TRegistrationId& aRegistrationId,
+ TTransactionId& aTransactionId,
+ CSIPRequest* aRequest,
+ const MRegistrationOwner* aOwner)
+ {
+ __SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+
+ __SIP_MESSAGE_LOG("Registration::UnRegisterL", *aRequest)
+
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId,aOwner);
+
+ // leave if binding doesn't exist
+ __ASSERT_ALWAYS (binding, User::Leave(KErrSIPInvalidRegistrationState));
+
+ TSIPRegistrationUtility::CheckUnregisterRequestL(*aRequest, *binding);
+
+ // if UnregisterL fails the binding must be detached from binding store
+ // and deleted. the cleanupItem detaches binding from binding store.
+ TCleanupItem cleanupItem(DetachBinding, binding);
+ CleanupStack::PushL(binding);
+ CleanupStack::PushL(cleanupItem);
+ // send request
+ binding->CurrentState().UnregisterL(aTransactionId, aRequest);
+ CleanupStack::Pop(); // cleanupItem
+ CleanupStack::Pop(binding);
+
+ binding->SetRequest(aRequest); // take ownership of aRequest
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::SetOutboundProxyL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::SetOutboundProxyL (
+ const TRegistrationId& aRegistrationId,
+ CSIPRouteHeader* aOutboundProxy,
+ const MRegistrationOwner* aOwner)
+ {
+ __SIP_ASSERT_LEAVE(aOutboundProxy, KErrArgument);
+
+ __ASSERT_ALWAYS(aOutboundProxy->SIPAddress().URI().IsSIPURI(),
+ User::Leave(KErrSipCodecURIScheme));
+
+ iBindingStore->SetOutboundProxyL(aRegistrationId,aOutboundProxy,aOwner);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::RemoveOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationMgr::RemoveOutboundProxy (
+ const TRegistrationId& aRegistrationId,
+ const MRegistrationOwner* aOwner)
+ {
+ return (iBindingStore->RemoveOutboundProxy(aRegistrationId,aOwner));
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::FetchRegistrationsL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::FetchRegistrationsL (
+ const TSIPTransportParams& aTransportParams,
+ TTransactionId& aTransactionId,
+ CSIPRequest* aRequest,
+ CURIContainer& aRemoteTarget,
+ MTransactionOwner* aTransactionOwner)
+ {
+ __SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+ __SIP_ASSERT_LEAVE(aTransactionOwner, KErrArgument);
+
+ __SIP_MESSAGE_LOG("Registration::FetchRegistrationsL", *aRequest)
+
+ TSIPRegistrationUtility::CheckFetchingRequestL(*aRequest);
+
+ if (aRemoteTarget.IsSIPURI())
+ {
+ aRemoteTarget.SIPURI()->DeleteUserInfo(); // user and password
+ }
+
+ iTU.SendL(aTransactionId, KEmptyRegistrationId, aRequest,
+ aTransactionOwner, aRemoteTarget, aTransportParams, ETrue);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::GetRouteL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::GetRouteL (
+ const TRegistrationId& aRegistrationId,
+ RPointerArray<CSIPRouteHeader>& aRouteSet,
+ TBool aAddOutboundProxy)
+ {
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+
+ if (binding)
+ {
+ const CSIPRouteHeader* proxy = binding->OutboundProxy();
+ if (proxy && aAddOutboundProxy)
+ {
+ aRouteSet.AppendL(proxy);
+ }
+
+ for (TInt i = 0; i < binding->RouteSet().Count(); i++)
+ {
+ CSIPRouteHeader* routeHeader = (binding->RouteSet())[i];
+ aRouteSet.AppendL(routeHeader);
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::CreateFromLC
+// -----------------------------------------------------------------------------
+//
+CSIPFromHeader* CSIPRegistrationMgr::CreateFromLC (
+ const TRegistrationId& aRegistrationId)
+ {
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+
+ __ASSERT_ALWAYS(binding, User::Leave(KErrNotFound));
+
+ CSIPFromHeader* from = NULL;
+ if (binding->PAssociatedURIHeader())
+ {
+ CSIPAddress* sipAddress =
+ CSIPAddress::NewLC(binding->PAssociatedURIHeader()->SIPAddress());
+ from = CSIPFromHeader::NewL(sipAddress);
+ CleanupStack::Pop(sipAddress);
+ CleanupStack::PushL(from);
+ }
+ else
+ {
+ from = CSIPFromHeader::NewLC(binding->AOR());
+ }
+ return from;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::ClearRegistrationOwner
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationMgr::ClearRegistrationOwner (
+ const MRegistrationOwner* aRegistrationOwner)
+ {
+ return (iBindingStore->ClearRegistrationOwner(aRegistrationOwner));
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::TerminateRegistration
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegistrationMgr::TerminateRegistration (
+ const TRegistrationId& aRegistrationId,
+ const MRegistrationOwner* aOwner)
+ {
+ return iBindingStore->RemoveBinding(aRegistrationId,aOwner);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::CheckRequestURI
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationMgr::CheckRequestURI(CURIContainer& aRequestUri)
+ {
+ return (iBindingStore->CheckRequestURI(aRequestUri));
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::OutboundProxy
+// -----------------------------------------------------------------------------
+//
+const CSIPRouteHeader* CSIPRegistrationMgr::OutboundProxy(
+ TRegistrationId aRegistrationId)
+ {
+ return iBindingStore->OutboundProxy(aRegistrationId);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::HasOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationMgr::HasOutboundProxy(
+ TRegistrationId aRegistrationId) const
+ {
+ return iBindingStore->HasOutboundProxy(aRegistrationId);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::IsOutboundProxy
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationMgr::IsOutboundProxy (const CURIContainer& aUri)
+ {
+ return iBindingStore->IsOutboundProxy(aUri);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::URIFailed
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::URIFailed (CURIContainer& aUri)
+ {
+ iBindingStore->URIFailed(aUri);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::ContactL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::ContactL(TUint32 aIapId,
+ TRegistrationId aRegistrationId,
+ const CSIPFromToHeaderBase* aFromToHeader,
+ CSIPContactHeader& aContact)
+ {
+ __SIP_ASSERT_LEAVE(aFromToHeader != 0, KErrArgument);
+ __SIP_ASSERT_LEAVE(aContact.SIPAddress() != 0, KErrArgument);
+
+ if (aContact.SIPAddress()->URI().IsSIPURI())
+ {
+ CSIPURI& contactSIPURI = *(aContact.SIPAddress()->URI().SIPURI());
+
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+ if (binding)
+ {
+ CSIPURI* bindingContactURI =
+ binding->Contact().SIPAddress()->URI().SIPURI();
+ __SIP_ASSERT_LEAVE(bindingContactURI != 0, KErrArgument);
+ CSIPHostPort* hostPort =
+ CSIPHostPort::NewLC(bindingContactURI->HostPort());
+ contactSIPURI.SetHostPortL(hostPort);
+ CleanupStack::Pop(hostPort);
+ }
+ else
+ {
+ FillHostWithLocalIPL(aIapId,contactSIPURI);
+ }
+
+ if (contactSIPURI.User().Length() == 0 &&
+ !iBindingStore->FindContactByFromL(aFromToHeader,aContact))
+ {
+ const CSIPURI* uriOfFromTo =
+ (const_cast<CSIPFromToHeaderBase*>(
+ aFromToHeader))->SIPAddress().URI().SIPURI();
+
+ __ASSERT_ALWAYS (uriOfFromTo != 0, User::Leave(KErrArgument));
+ __ASSERT_ALWAYS (uriOfFromTo->User().Length() > 0,
+ User::Leave(KErrSIPInvalidContact));
+
+ contactSIPURI.SetUserL(uriOfFromTo->User());
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::Contact
+// -----------------------------------------------------------------------------
+//
+const CSIPContactHeader* CSIPRegistrationMgr::Contact (
+ const TRegistrationId& aRegistrationId)
+ {
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+
+ if (binding)
+ {
+ return &(binding->Contact());
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::FillTransportParams
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationMgr::FillTransportParams(
+ const TRegistrationId& aRegistrationId,
+ TSIPTransportParams& aTransportParams)
+ {
+ TBool found = EFalse;
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+ if (binding)
+ {
+ found = ETrue;
+ aTransportParams = binding->FillTransportParams();
+ }
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::SIPSecUser
+// -----------------------------------------------------------------------------
+//
+const MSIPSecUser* CSIPRegistrationMgr::SIPSecUser(
+ const TRegistrationId& aRegistrationId)
+ {
+ return iBindingStore->FindBinding(aRegistrationId);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::SIPSecUserForTransaction
+// -----------------------------------------------------------------------------
+//
+const MSIPSecUser* CSIPRegistrationMgr::SIPSecUserForTransaction(
+ const TTransactionId& aTransactionId)
+ {
+ return iBindingStore->FindBindingForTransaction(aTransactionId);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::ConnectionStateChangedL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::ConnectionStateChangedL (
+ TUint32 aIapId,
+ CSIPConnection::TState aState)
+ {
+ if (aState == CSIPConnection::EInactive ||
+ aState == CSIPConnection::EUnavailable)
+ {
+ // remove bindings, which has same IAPId.
+ iBindingStore->RemoveBindingByIAPId(aIapId);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::FillHostWithLocalIPL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::FillHostWithLocalIPL (TUint32 aIapId,
+ CSIPURI& aSipUri)
+ {
+ HBufC8* localAddr = TSIPRegistrationUtility::LocalAddressLC(aIapId, iTU);
+ aSipUri.HostPort().SetHostL(*localAddr);
+ CleanupStack::PopAndDestroy(localAddr);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::DetachBinding
+// -----------------------------------------------------------------------------
+//
+void CSIPRegistrationMgr::DetachBinding (TAny* aBinding)
+ {
+ __SIP_ASSERT_RETURN(aBinding, KErrGeneral);
+
+ CSIPRegistrationBindingBase* binding =
+ reinterpret_cast<CSIPRegistrationBinding*>(aBinding);
+
+ binding->DetachFromStore();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::IsCacheOutboundProxyIPEanbled
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegistrationMgr::IsCacheOutboundProxyIPEanbled(
+ TRegistrationId aRegistrationId) const
+ {
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+ if (binding)
+ {
+ return binding->IsCacheOutboundProxyIPEnabled();
+ }
+ return EFalse;
+ }
+// -----------------------------------------------------------------------------
+// CSIPRegistrationMgr::OutboundProxyIPL
+// -----------------------------------------------------------------------------
+//
+CSIPRouteHeader& CSIPRegistrationMgr::OutboundProxyIPL(
+ TRegistrationId aRegistrationId) const
+ {
+ CSIPRegistrationBindingBase* binding =
+ iBindingStore->FindBinding(aRegistrationId);
+ __SIP_ASSERT_LEAVE(binding, KErrArgument);
+ return binding->OutboundProxyIPL();
+ }