diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Registration/src/CSIPRegistrationBindingBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Registration/src/CSIPRegistrationBindingBase.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,1139 @@ +// Copyright (c) 2007-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 : CSIPRegistrationBindingBase.cpp +// Part of : Registration +// Version : SIP/6.0 +// + + + +#include "CSIPRegistrationRefreshBinding.h" +#include "CSIPRegistrationBinding.h" +#include "TSIPRegistrationUtility.h" +#include "CSIPRegistrar.h" +#include "CSIPRegistrarStore.h" +#include "CSIPRegistrationBindingStore.h" +#include "CSIPResponseUtility.h" +#include "MRegistrationOwner.h" +#include "sipresponse.h" +#include "siprequest.h" +#include "siptoheader.h" +#include "sipfromheader.h" +#include "sipaddress.h" +#include "sipcontactheader.h" +#include "uricontainer.h" +#include "sipuri.h" +#include "siphostport.h" +#include "siprouteheader.h" +#include "sipminexpiresheader.h" +#include "sipservicerouteheader.h" +#include "sippassociateduriheader.h" +#include "MSigComp.h" +#include "sipsec.h" +#include "siperr.h" +#include "SipLogs.h" +#include "SipAssert.h" +#include "sipcodecutils.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "csipregistering.h" +#include "csip423responsereceived.h" +#include "csipregistered.h" +#include "csipregisterupdating.h" +#include "csipunregistering.h" +#include "csipunregistered.h" +#include "TSIPTransportParams.h" +#include "MSIPTransportMgr.h" +#include + + +#define HEADER(H, M, N) static_cast((M).Header(N,0)) +const TUint KDefaultSipPort = 5060; + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ConstructL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::ConstructL(CSIPRequest* aSIPRequest, + CURIContainer& aRemoteTarget) + { + __ASSERT_ALWAYS (aSIPRequest, User::Leave (KErrArgument)); + __ASSERT_ALWAYS (aSIPRequest->To(), User::Leave (KErrArgument)); + __ASSERT_ALWAYS (aSIPRequest->From(), User::Leave (KErrArgument)); + + InitializeStatesL(); + + // copy to header from request + SetToHeaderL(*aSIPRequest); + + // copy from header from request + SetFromHeaderL(*aSIPRequest); + + // copy contact header from request. + SetContactHeaderL(*aSIPRequest); + + iRegistrationId = iBindingStore.NextRegistrationId(); + + iRegistrar = iBindingStore.RegistrarStore().FindRegistrar(aRemoteTarget); + + if (!iRegistrar) // registrar not found + { + iRemoteTarget = CURIContainer::NewL(aRemoteTarget); + } + else + { + iRegistrar->AddRegistrationIdL(iRegistrationId); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::InitializeStatesL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::InitializeStatesL() + { + iRegistering = CSIPRegistering::NewL(*this); + iRegistered = CSIPRegistered::NewL(*this); + iResponse423Received = CSIP423ResponseReceived::NewL(*this); + iUpdating = CSIPRegisterUpdating::NewL(*this); + iUnregistering = CSIPUnregistering::NewL(*this); + iUnregistered = CSIPUnregistered::NewL(*this); + + // set registering neighbour states. + iRegistering->SetNeighbourStates(iResponse423Received, iRegistered, + iUnregistered); + // set current state to registering. + iCurrentState = iRegistering; + // set registered neighbour states. + iRegistered->SetNeighbourStates(iUpdating, iUnregistering, iUnregistered, + iResponse423Received); + // set response 423 received neighbour states. + iResponse423Received->SetNeighbourStates(iRegistered, iUnregistered); + // set unregistering states. + iUnregistering->SetNeighbourStates(iUnregistered); + // set updating states. + iUpdating->SetNeighbourStates(iResponse423Received, iRegistered, + iUnregistered); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::CSIPRegistrationBindingBase +// ----------------------------------------------------------------------------- +// +CSIPRegistrationBindingBase::CSIPRegistrationBindingBase ( + MTransactionUser& aTransactionUser, + MSigComp& aSigComp, + CSIPSec& aSIPSec, + CSIPRegistrationBindingStore& aBindingStore, + MRegistrationOwner* aRegistrationOwner, + MSIPSecUser& aSIPSecUser, + MSIPTransportMgr& aTransportMgr, + TBool aSendWithExpires, + TBool aCacheOutboundProxyIP) + : iTransactionUser (aTransactionUser), + iOwner (aRegistrationOwner), + iRegistrationId (KEmptyRegistrationId), + iSIPSecUser (aSIPSecUser), + iSigComp (aSigComp), + iSIPSec (aSIPSec), + iBindingStore (aBindingStore), + iTransportMgr (aTransportMgr), + iSendWithExpires (aSendWithExpires), + iCacheOutboundProxyIP(aCacheOutboundProxyIP) + { + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::~CSIPRegistrationBindingBase +// ----------------------------------------------------------------------------- +// +CSIPRegistrationBindingBase::~CSIPRegistrationBindingBase() + { + if (iRegistrar) + { + iRegistrar->BindingRemoved(iRegistrationId); + } + FreeProxyTransportResources(); + delete iPAssociatedURIHeader; + delete iOutboundProxy; + delete iOutboundProxyIP; + delete iTo; + delete iFrom; + delete iContact; + delete iRemoteTarget; + iRouteSet.ResetAndDestroy(); + delete iRequest; + + // delete register states + delete iRegistering; + delete iRegistered; + delete iResponse423Received; + delete iUpdating; + delete iUnregistering; + delete iUnregistered; + iTransportMgr.RemoveTransport(iTransportId); + iSIPSec.ClearCache(this); + iTransactionUser.FreeResources(*this); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::PassOnlyRealmsToUser +// From MSIPSecUser +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::PassOnlyRealmsToUser() const + { + return iSIPSecUser.PassOnlyRealmsToUser(); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RequestCredentialsL +// From MSIPSecUser +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::RequestCredentialsL(const TDesC8& aRealm) + { + iSIPSecUser.RequestCredentialsL(aRealm); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RequestCredentialsL +// From MSIPSecUser +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::RequestCredentialsL( + CSIPResponse& aResponse, + TTransactionId aTransactionId, + TRefreshId aRefreshId) + { + iSIPSecUser.RequestCredentialsL(aResponse,aTransactionId,aRefreshId); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::TrustedUser +// From MSIPSecUser +// ----------------------------------------------------------------------------- +// +const MSIPSecUser* CSIPRegistrationBindingBase::TrustedUser( + TRegistrationId /*aRegistrationId*/) + { + return NULL; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ByPassSIPSec +// From MSIPSecUser +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::ByPassSIPSec() const + { + return iSIPSecUser.ByPassSIPSec(); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::FlowFailure +// From MSIPNATBindingObserver +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::FlowFailure(TInt /*aError*/) + { + iOwner->RegistrationError(iTransactionId,iRegistrationId, + KErrSIPTransportFailure); + ChangeState(iUnregistered); + iTransactionUser.FreeResources(*this); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RefreshId +// ----------------------------------------------------------------------------- +// +TRefreshId CSIPRegistrationBindingBase::RefreshId() const + { + return KEmptyRefreshId; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetRequest +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetRequest (CSIPRequest* aSIPRequest) + { + delete iRequest; + iRequest = aSIPRequest; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Owner +// ----------------------------------------------------------------------------- +// +const MRegistrationOwner* CSIPRegistrationBindingBase::Owner() const + { + return iOwner; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RegisterPending +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::RegisterPending () const + { + // return ETrue when binding is in following states. + return (iCurrentState == iRegistering || + iCurrentState == iUpdating || + iCurrentState == iUnregistering || + iCurrentState == iResponse423Received); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::UpdateBindingFromResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::UpdateBindingFromResponseL( + CSIPResponse& aResponse) + { + // no related registrar, create one, add registrar pointer to binding + if (!iRegistrar) + { + HBufC8* callId = CSIPResponseUtility::CallIdL(aResponse); + CleanupStack::PushL(callId); + iRegistrar = iBindingStore.RegistrarStore().CreateRegistrarL( + *iRemoteTarget, *callId, + CSIPResponseUtility::CSeqValueL(aResponse), iRegistrationId); + CleanupStack::PopAndDestroy(callId); + delete iRemoteTarget; + iRemoteTarget = NULL; + } + + const RStringF KTagParam = SIPStrings::StringF(SipStrConsts::ETag); + if ((aResponse.From()) && (aResponse.From()->HasParam(KTagParam))) + { + iFrom->SetParamL(KTagParam,aResponse.From()->ParamValue(KTagParam)); + } + SetRouteHeaderFromResponseL(aResponse); + SetPAssociatedURIFromResponseL(aResponse); + } + + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetToHeaderL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetToHeaderL(CSIPRequest& aSIPRequest) + { + CSIPToHeader* to = aSIPRequest.To(); + CSIPToHeader* tempTo = CSIPToHeader::NewL(*to); + delete iTo; + iTo = tempTo; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetFromHeaderL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetFromHeaderL(CSIPRequest& aSIPRequest) + { + CSIPFromHeader* fromHeader = aSIPRequest.From(); + + CSIPFromHeader* temp = CSIPFromHeader::NewL(*fromHeader); + delete iFrom; + iFrom = temp; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetContactHeaderL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetContactHeaderL(CSIPRequest& aSIPRequest) + { + const RStringF KContactHeaderName = + SIPStrings::StringF(SipStrConsts::EContactHeader); + + CSIPContactHeader* contact = + HEADER(CSIPContactHeader, aSIPRequest, KContactHeaderName); + + CSIPContactHeader* tmp = static_cast(contact->CloneL()); + CleanupStack::PushL(tmp); + if(iContact && tmp->ExpiresParameter() == KErrNotFound) + tmp->SetExpiresParameterL(iContact->ExpiresParameter()); + delete iContact; + CleanupStack::Pop(tmp); + iContact = tmp; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetExpiresValueL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetExpiresValueL(CSIPRequest& aSIPRequest) + { + const RStringF KContactHeaderName = + SIPStrings::StringF(SipStrConsts::EContactHeader); + + CSIPContactHeader* contactHeader = + HEADER(CSIPContactHeader, aSIPRequest, KContactHeaderName); + + iContact->SetExpiresParameterL(contactHeader->ExpiresParameter()); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetMinExpiresToRequestL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetMinExpiresToRequestL ( + CSIPResponse& aResponse) + { + const RStringF KContactHeaderName = + SIPStrings::StringF(SipStrConsts::EContactHeader); + + // the request must not be empty + __SIP_ASSERT_LEAVE(iRequest, KErrArgument); + __SIP_ASSERT_LEAVE(iRequest->HasHeader(KContactHeaderName), + KErrArgument); + // get the Min expires header from response + CSIPMinExpiresHeader* minExpiresHeader = HEADER( + CSIPMinExpiresHeader, aResponse, + SIPStrings::StringF(SipStrConsts::EMinExpiresHeader)); + // get contact header from request + CSIPContactHeader* contactInRequest = HEADER( + CSIPContactHeader, *iRequest, KContactHeaderName); + // set the min expires value to contact in the original request + contactInRequest->SetExpiresParameterL(minExpiresHeader->Value()); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetRouteHeaderFromResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetRouteHeaderFromResponseL( + CSIPResponse& aResponse) + { + iRouteSet.ResetAndDestroy(); + + TSglQueIter iter = + aResponse.Headers( + SIPStrings::StringF(SipStrConsts::EServiceRouteHeader)); + + for (CSIPHeaderBase* header = iter++; header; header = iter++) + { + CSIPServiceRouteHeader* routeHeader = + static_cast(header); + CSIPRouteHeader* newRouteHeader = + SIPCodecUtils::CreateRouteHeaderLC(*routeHeader); + iRouteSet.AppendL(newRouteHeader); + CleanupStack::Pop(newRouteHeader); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ServiceRouteOk +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::ServiceRouteOk( + CSIPResponse& aResponse) const + { + // Check if the last Service-Route-header has changed + TBool ok = ETrue; + if (iRouteSet.Count() > 0) + { + TInt headerCount = + aResponse.HeaderCount( + SIPStrings::StringF(SipStrConsts::EServiceRouteHeader)); + if (headerCount > 0) + { + CSIPRouteHeaderBase* myLastRoute = iRouteSet[iRouteSet.Count()-1]; + + CSIPRouteHeaderBase* newLastRoute = + static_cast( + aResponse.Header( + SIPStrings::StringF(SipStrConsts::EServiceRouteHeader), + headerCount-1)); + + ok = (myLastRoute->SIPAddress() == newLastRoute->SIPAddress()); + } + } + return ok; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetPAssociatedURIFromResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetPAssociatedURIFromResponseL( + CSIPResponse& aResponse) + { + CSIPHeaderBase* headerInResponse = + aResponse.Header( + SIPStrings::StringF(SipStrConsts::EPAssociatedURIHeader),0); + CSIPHeaderBase* header = NULL; + if (headerInResponse) + { + header = headerInResponse->CloneL(); + } + delete iPAssociatedURIHeader; + iPAssociatedURIHeader = static_cast(header); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::PAssociatedURIHeader +// ----------------------------------------------------------------------------- +// +const CSIPPAssociatedURIHeader* +CSIPRegistrationBindingBase::PAssociatedURIHeader() const + { + return iPAssociatedURIHeader; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::FillTransportParams +// ----------------------------------------------------------------------------- +// +TSIPTransportParams CSIPRegistrationBindingBase::FillTransportParams() + { + TSIPTransportParams transportParams(iOwner->TransportParams()); + transportParams.SetTransportId(iTransportId); + transportParams.SetCompartmentId(iSigCompCompartmentId); + transportParams.SetNATBindingObserver(this); + return transportParams; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::HasTransaction +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::HasTransaction( + const TTransactionId& aTransactionId) const + { + return (iTransactionId == aTransactionId || + iRetryTransactionId == aTransactionId); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::OutboundProxyFailed +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::OutboundProxyFailed() + { + if (!RegisterPending()) + { + iCurrentState->TransactionEnded(KEmptyTransactionId, + KErrSIPOutboundProxyNotResponding); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RouteSet +// ----------------------------------------------------------------------------- +// +RPointerArray& CSIPRegistrationBindingBase::RouteSet() + { + return iRouteSet; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::IAPId +// ----------------------------------------------------------------------------- +// +TUint32 CSIPRegistrationBindingBase::IAPId() const + { + return iOwner->TransportParams().IapId(); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SigCompCompartmentId +// ----------------------------------------------------------------------------- +// +TUint32 CSIPRegistrationBindingBase::SigCompCompartmentId() const + { + return iSigCompCompartmentId; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Contact +// ----------------------------------------------------------------------------- +// +CSIPContactHeader& CSIPRegistrationBindingBase::Contact() + { + return *iContact; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::AOR +// ----------------------------------------------------------------------------- +// +const CSIPToHeader& CSIPRegistrationBindingBase::AOR () const + { + return *iTo; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::FindContactByFromL +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::FindContactByFromL( + const CSIPFromToHeaderBase* aFromToHeader, + CSIPContactHeader& aContact) + { + TBool found = EFalse; + + const CURIContainer& uriOfFromTo = (const_cast( + aFromToHeader))->SIPAddress().URI(); + + // if URI of To header in binding == URI of aFromToHeader header + if (uriOfFromTo.IsSIPURI() && + iTo->SIPAddress().URI().IsSIPURI() && + iTo->SIPAddress().URI() == uriOfFromTo) + { + CSIPURI& sipuri = *aContact.SIPAddress()->URI().SIPURI(); + CSIPURI& sipuriInBinding = *iContact->SIPAddress()->URI().SIPURI(); + + if (sipuri.User().Length() > 0) + { + if (sipuri.User().Compare(sipuriInBinding.User()) == 0) + { + // fill in host part + CSIPHostPort* hostPort = + CSIPHostPort::NewLC(sipuriInBinding.HostPort()); + sipuri.SetHostPortL(hostPort); + CleanupStack::Pop(hostPort); + found = ETrue; + } + } + else + { + // fill in user part + sipuri.SetUserL(sipuriInBinding.User()); + // fill in host part + CSIPHostPort* hostPort = + CSIPHostPort::NewLC(sipuriInBinding.HostPort()); + sipuri.SetHostPortL(hostPort); + CleanupStack::Pop(hostPort); + found = ETrue; + } + } + + return found; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::CompareWithRegisterRequest +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::CompareWithRegisterRequest( + const MRegistrationOwner& aRegistrationOwner, + CSIPRequest& aSIPRequest) + { + TBool returnValue = EFalse; + + if (iOwner == &aRegistrationOwner) + { + // get To header from request + CSIPToHeader* toHeader = aSIPRequest.To(); + CURIContainer& uriOfToInReq = toHeader->SIPAddress().URI(); + + // get From header from request + CSIPFromHeader* fromHeader = aSIPRequest.From(); + CURIContainer& uriOfFromInReq = fromHeader->SIPAddress().URI(); + + // get Contact header from request + CSIPContactHeader* contactHeader = HEADER( + CSIPContactHeader, aSIPRequest, + SIPStrings::StringF(SipStrConsts::EContactHeader)); + + CURIContainer& uriOfContactInReq = contactHeader->SIPAddress()->URI(); + CURIContainer& uriOfTo = iTo->SIPAddress().URI(); + CURIContainer& uriOfFrom = iFrom->SIPAddress().URI(); + CURIContainer& uriOfContact = iContact->SIPAddress()->URI(); + + if ((uriOfToInReq == uriOfTo) && + (uriOfFromInReq == uriOfFrom) && + (uriOfContactInReq == uriOfContact)) + { + returnValue = ETrue; + } + } + + return returnValue; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RegistrationId +// ----------------------------------------------------------------------------- +// +TRegistrationId CSIPRegistrationBindingBase::RegistrationId() const + { + return iRegistrationId; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::OutboundProxy +// ----------------------------------------------------------------------------- +// +const CSIPRouteHeader* CSIPRegistrationBindingBase::OutboundProxy() + { + return iOutboundProxy; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::HasOutboundProxy +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::HasOutboundProxy() const + { + return (iOutboundProxy != 0); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetOutboundProxy +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetOutboundProxy( + CSIPRouteHeader* aOutboundProxy) + { + __SIP_ASSERT_RETURN (aOutboundProxy, KErrArgument); + + delete iOutboundProxy; + iOutboundProxy = aOutboundProxy; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetOutboundProxyL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SetOutboundProxyL( + CSIPRouteHeader* aOutboundProxy) + { + __SIP_ASSERT_LEAVE (aOutboundProxy, KErrArgument); + + CreateProxyTransportResourcesL(*aOutboundProxy); + SetOutboundProxy(aOutboundProxy); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RemoveOutboundProxy +// ----------------------------------------------------------------------------- +// +TInt CSIPRegistrationBindingBase::RemoveOutboundProxy() + { + TInt err = KErrNotFound; + if (iOutboundProxy) + { + FreeProxyTransportResources(); + delete iOutboundProxy; + iOutboundProxy = NULL; + err = KErrNone; + } + return err; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RemoveBinding +// ----------------------------------------------------------------------------- +// +TInt CSIPRegistrationBindingBase::RemoveBinding () + { + TInt err = iBindingStore.RemoveBinding (this); + + if (err == KErrNone && iRegistrar) + { + if(iRegistrar->BindingRemoved(iRegistrationId)) + { + iRegistrar = NULL; + } + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::CreateProxyTransportResourcesL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::CreateProxyTransportResourcesL ( + CSIPRouteHeader& aOutboundProxy) + { + CURIContainer& uri = aOutboundProxy.SIPAddress().URI(); + TUint32 oldCompartmentId = iSigCompCompartmentId; + if (uri.IsSIPURI() && HasSigCompParameter(*uri.SIPURI())) + { + iSigCompCompartmentId = iSigComp.CreateCompartmentL(IAPId()); + } + else + { + iSigCompCompartmentId = 0; + } + iSigComp.RemoveCompartment(oldCompartmentId); + TUint32 oldTransportId = iTransportId; + if (uri.IsSIPURI() && uri.SIPURI()->IsSIPSURI()) + { + TSIPTransportParams transportParams(FillTransportParams()); + iTransportMgr.CreateTLSTransportL(transportParams); + iTransportId = transportParams.TransportId(); + } + else + { + iTransportId = 0; + } + iTransportMgr.RemoveTransport(oldTransportId); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::FreeProxyTransportResources +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::FreeProxyTransportResources() + { + if (iSigCompCompartmentId) + { + iSigComp.RemoveCompartment(iSigCompCompartmentId); + iSigCompCompartmentId = 0; + } + if (iTransportId) + { + iTransportMgr.RemoveTransport(iTransportId); + iTransportId = 0; + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::HasSigCompParameter +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::HasSigCompParameter ( + const CSIPURI& aUri) const + { + RStringF comp = SIPStrings::StringF(SipStrConsts::EComp); + RStringF sigcomp = SIPStrings::StringF(SipStrConsts::ESigComp); + return (iSigComp.IsSupported() && aUri.ParamValue(comp) == sigcomp); + } + + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::RegisterL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::RegisterL(TTransactionId& aTransactionId, + CSIPRequest* aRequest, + CSIPRouteHeader* aOutboundProxy) + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + if(!iSendWithExpires) + TSIPRegistrationUtility::RemoveRegisterExpiresParam(*aRequest); + DoRegisterL(aTransactionId, aRequest, aOutboundProxy); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::UpdateL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::UpdateL(TTransactionId& aTransactionId, + CSIPRequest* aRequest) + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + if(!iSendWithExpires) + TSIPRegistrationUtility::RemoveRegisterExpiresParam(*aRequest); + DoUpdateL(aTransactionId, aRequest); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::UnregisterL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::UnregisterL(TTransactionId& aTransactionId, + CSIPRequest* aRequest) + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + DoUnregisterL(aTransactionId, aRequest); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Registrar +// ----------------------------------------------------------------------------- +// +CSIPRegistrar* CSIPRegistrationBindingBase::Registrar() + { + return iRegistrar; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::FillToFromL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::FillToFromL(CSIPRequest& aRequest) + { + // fill in to header from binding + CSIPToHeader* to = aRequest.To(); + if (!to) + { + to = CSIPToHeader::NewLC(*iTo); + aRequest.AddHeaderL(to); + CleanupStack::Pop(to); + } + + // fill in from header from binding + CSIPFromHeader* from = aRequest.From(); + if (!from) + { + from = CSIPFromHeader::NewLC(*iFrom); + aRequest.AddHeaderL(from); + CleanupStack::Pop(from); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::CurrentState +// ----------------------------------------------------------------------------- +// +CSIPRegistrationState& CSIPRegistrationBindingBase::CurrentState() + { + return *iCurrentState; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ChangeState +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::ChangeState(CSIPRegistrationState* aState) + { + iCurrentState = aState; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Request +// ----------------------------------------------------------------------------- +// +CSIPRequest* CSIPRegistrationBindingBase::Request() + { + return iRequest; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::UpdateContactFromRequestL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::UpdateContactFromRequestL() + { + if (iRequest) + { + SetContactHeaderL(*iRequest); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SelfDetach +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SelfDetach(TBool aRefresh) + { + if (IsRefresh()) + { + if (aRefresh) + { + static_cast(this)-> + ClearRefreshOwner(); + } + } + else + { + static_cast(this)->ClearTransactionOwner(); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SelfDetach +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::SelfDetach(TBool aRefresh, TBool aUseRetryId) + { + if( !IsRefresh() && aUseRetryId ) + { + static_cast(this)-> + ClearTransactionOwner( aUseRetryId ); + } + else + { + SelfDetach( aRefresh ); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Received2XXResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::Received2XXResponseL(CSIPResponse& aResponse, + TTransactionId aTransactionId) + { + if (iRequest) + { + // Update the From- and To-headers in case some parameters have changed + SetToHeaderL(*iRequest); + SetFromHeaderL(*iRequest); + } + + UpdateBindingFromResponseL(aResponse); + if (HasOutboundProxy() && iCacheOutboundProxyIP) + SetOutboundProxyIPL(aTransactionId); + if (!IsRefresh()) + { + // start timer for non refresh binding + static_cast(this)->StartTimerL( + CSIPResponseUtility::ExpireValueL(*iContact, aResponse)); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ClearRequest +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::ClearRequest() + { + if (!IsRefresh() && iRequest) + { + delete iRequest; + iRequest = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ReceivedErrorResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::ReceivedErrorResponseL() + { + // return KErrNotFound when binding could not found, + // return KErrNone when binding is found and is added to delete manager + TInt err = RemoveBinding (); + + // leaves if binding is found and it is not added to delete manager + if (err != KErrNotFound && err != KErrNone) + { + User::Leave(err); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::Received423ResponseL +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::Received423ResponseL(CSIPResponse& aResponse) + { + // set min expires value to request contact header. + SetMinExpiresToRequestL(aResponse); + // detaching "this" registration from lower layer. + SelfDetach(ETrue); + // set refresh id to KEmptyRefreshId if it's refresh binding + if (IsRefresh()) + { + static_cast(this)->SetRefreshId( + KEmptyRefreshId); + } + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::DetachFromStore +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::DetachFromStore() + { + iBindingStore.DetachBinding(this); + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::DetachOutboundProxy +// ----------------------------------------------------------------------------- +// +void CSIPRegistrationBindingBase::DetachOutboundProxy(TAny* aBinding) + { + __SIP_ASSERT_RETURN(aBinding, KErrGeneral); + + CSIPRegistrationBindingBase* binding = + reinterpret_cast(aBinding); + + binding->FreeProxyTransportResources(); + binding->iOutboundProxy = NULL; // detach the OutboundProxy + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::SetOutboundProxyIPL +// ----------------------------------------------------------------------------- +// +TInt CSIPRegistrationBindingBase::SetOutboundProxyIPL(const TTransactionId& aTransactionId) + { + TInetAddr outboundProxyIP; + TInt error = iTransactionUser.NextHopIP(aTransactionId, outboundProxyIP); + if (!error) + { + CSIPAddress* sipAddress = CSIPAddress::NewLC(iOutboundProxy->SIPAddress()); + + HBufC8* addressText = ConvertInetAddrToTextL(outboundProxyIP); + CleanupStack::PushL(addressText); + CSIPHostPort* hostport = CSIPHostPort::DecodeL( *addressText ); + CleanupStack::PopAndDestroy(addressText); + CleanupStack::PushL(hostport); + + TUint port = outboundProxyIP.Port() > 0 ? + outboundProxyIP.Port() : KDefaultSipPort; + hostport->SetPort(port); + + sipAddress->URI().SIPURI()->SetHostPortL(hostport); + + sipAddress->URI().SIPURI()->SetSIPS( + iOutboundProxy->SIPAddress().URI().SIPURI()->IsSIPSURI()); + + CleanupStack::Pop(hostport); + delete iOutboundProxyIP; + iOutboundProxyIP = NULL; + iOutboundProxyIP = CSIPRouteHeader::NewL(sipAddress); + CleanupStack::Pop(sipAddress); + } + return error; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::ConvertInetAddrToTextL +// ----------------------------------------------------------------------------- +// +HBufC8* CSIPRegistrationBindingBase::ConvertInetAddrToTextL(const TInetAddr& aAddr) + { + const TInt KMaxIPAddrLen = 256; + HBufC* addressOut = HBufC::NewLC(KMaxIPAddrLen); + TPtr outputPtr(addressOut->Des()); + aAddr.Output(outputPtr); + + HBufC8* addressResult = HBufC8::NewL(addressOut->Length()); + TPtr8 resultPtr(addressResult->Des()); + CnvUtfConverter::ConvertFromUnicodeToUtf8(resultPtr, *addressOut); + CleanupStack::PopAndDestroy(addressOut); + + return addressResult; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::IsCacheOutboundProxyIPEnabled +// ----------------------------------------------------------------------------- +// +TBool CSIPRegistrationBindingBase::IsCacheOutboundProxyIPEnabled() + { + return iCacheOutboundProxyIP; + } + +// ----------------------------------------------------------------------------- +// CSIPRegistrationBindingBase::OutboundProxyIPL +// ----------------------------------------------------------------------------- +// +CSIPRouteHeader& CSIPRegistrationBindingBase::OutboundProxyIPL() + { + __ASSERT_ALWAYS (iOutboundProxyIP, User::Leave (KErrNotSupported)); + return *iOutboundProxyIP; + } +