diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/sipapi/src/RegBindingImplementation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/sipapi/src/RegBindingImplementation.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,948 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : RegBindingImplementation.cpp +// Part of : SIPAPI +// Version : SIP/5.0 +// + + + +#include +#include "siperr.h" +#include "sipdefs.h" +#include "SipAssert.h" +#include "sipclientconnection.h" +#include "SipConnectionImplementation.h" +#include "RegBindingImplementation.h" +#include "sipregistrationstate.h" +#include "sipclienttransaction.h" +#include "sipmessageelements.h" +#include "sipresponseelements.h" +#include "siprefresh.h" +#include "siprouteheader.h" +#include "sipcontactheader.h" +#include "siptoheader.h" +#include "sipfromheader.h" +#include "sipconnectioncallback.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include + +#ifdef CPPUNIT_TEST +#include "TestCleanupStack.h" +#endif + + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::NewL +// ----------------------------------------------------------------------------- +// +CRegBindingImplementation* +CRegBindingImplementation::NewL(CSIPRegistrationBinding& aRegistration, + CSIPConnection& aConnection, + CSIPToHeader* aAor, + CSIPContactHeader* aContact, + CSIPRefresh* aRefresh, + CSIPRouteHeader* aOutboundProxy, + CUri8* aRemoteUri, + CSIPFromHeader* aFrom) + { + __ASSERT_ALWAYS(aAor && aContact, User::Leave(KErrArgument)); + + TInt expires = aContact->ExpiresParameter(); + __ASSERT_ALWAYS(expires >= static_cast(KSIPMinExpirationValue) || + expires == KErrNotFound, User::Leave(KErrArgument)); + CRegBindingImplementation* self = + new (ELeave) CRegBindingImplementation(aRegistration, aConnection); + CleanupStack::PushL(self); + self->ConstructL(aAor, + aContact, + aRefresh, + aOutboundProxy, + aRemoteUri, + aFrom); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::CRegBindingImplementation +// ----------------------------------------------------------------------------- +// +CRegBindingImplementation::CRegBindingImplementation( + CSIPRegistrationBinding& aRegistration, + CSIPConnection& aConnection) : + iRegistration(aRegistration), + iConnection(&aConnection) + { + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ConstructL +// aAor and aContact have been checked in NewLC so they aren't checked again +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::ConstructL(CSIPToHeader* aAor, + CSIPContactHeader* aContact, + CSIPRefresh* aRefresh, + CSIPRouteHeader* aOutboundProxy, + CUri8* aRemoteUri, + CSIPFromHeader* aFrom) + { + CheckConnectionL(); + + iConnection->Implementation().AddRegistrationL(*this); + iState = iConnection->Implementation().InitialRegisterStateL(); + iContact = aContact; + iAor = aAor; + iRefresh = aRefresh; + if (iRefresh) + { + iRefresh->SetRefreshOwner(*this); + iRefresh->SetRequestType(SIPStrings::StringF(SipStrConsts::ERegister)); + } + + iOutboundProxy = aOutboundProxy; + iRemoteUri = aRemoteUri; + iFrom = aFrom; + iSendWithExpires = ETrue; + iCacheOutboundProxyIP = EFalse; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::~CRegBindingImplementation +// ----------------------------------------------------------------------------- +// +CRegBindingImplementation::~CRegBindingImplementation() + { + if (iConnection) + { + CSIPClientConnection* clientConn = + iConnection->Implementation().ClientConnection(); + if (clientConn) + { + clientConn->TerminateRegistration(iRegistrationId); + } + iConnection->Implementation().RemoveRegistration(*this); + } + + for (TInt i = 0; i < iTransactions.Count(); i++) + { + iTransactions[i]->Detach(*this); + } + iTransactions.Reset(); + + delete iRefresh; + delete iOutboundProxy; + delete iContact; + delete iAor; + delete iRemoteUri; + delete iFrom; + delete iRegisteredContact; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::IsContextActive +// ----------------------------------------------------------------------------- +// +TBool CRegBindingImplementation::IsContextActive() const + { + __TEST_INVARIANT; + return iState && iState->IsContextActive(); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ContextId +// ----------------------------------------------------------------------------- +// +TUint32 CRegBindingImplementation::ContextId() const + { + __TEST_INVARIANT; + return iRegistrationId; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::RegisterL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::RegisterL(CSIPMessageElements* aElements) + { + __TEST_INVARIANT; + + CheckElementsL(aElements); + return StateL().RegisterL(*this, aElements); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DoRegisterL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::DoRegisterL(CSIPMessageElements* aElements) + { + __TEST_INVARIANT; + CheckConnectionL(); + + CSIPClientTransaction* ta = CreateClientTransactionL(); + CleanupStack::PushL(ta); + + CSIPMessageElements* elem = aElements; + if (!aElements) + { + elem = CSIPMessageElements::NewLC(); + } + + //Put contact temporarily to elem. Once REGISTER is sent, clear it from elem + CleanupStack::PushL(TCleanupItem(DetachContactHeader, elem)); + elem->AddHeaderL(iContact); + + CSIPFromHeader* from = iFrom; + if (!iFrom) + { + from = CSIPFromHeader::NewLC(*iAor); + } + + TUint32 requestId(0); + iConnection->Implementation().ClientConnectionL().SendRegisterL(requestId, + *iAor, + *from, + *elem, + iRemoteUri, + iOutboundProxy, + (iRefresh != NULL), + iSendWithExpires, + iCacheOutboundProxyIP); + if (!iFrom) + { + CleanupStack::PopAndDestroy(from); + } + CleanupStack::PopAndDestroy(); //TCleanupItem + + if (aElements) + { + delete aElements; + } + else + { + CleanupStack::PopAndDestroy(elem); + } + CleanupStack::Pop(ta); + ta->SetRequestId(requestId); + + __TEST_INVARIANT; + return ta; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DeregisterL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::DeregisterL(CSIPMessageElements* aElements) + { + __TEST_INVARIANT; + return StateL().DeregisterL(*this, aElements); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DoDeregisterL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::DoDeregisterL(CSIPMessageElements* aElements) + { + __TEST_INVARIANT; + CheckConnectionL(); + + CSIPClientTransaction* ta = CSIPClientTransaction::NewLC( + SIPStrings::StringF(SipStrConsts::ERegister), *this); + + TUint32 requestId(0); + iConnection->Implementation().ClientConnectionL().UnregisterL( + iRegistrationId, + requestId, + aElements); + CleanupStack::Pop(ta); + ta->SetRequestId(requestId); + delete aElements; + + __TEST_INVARIANT; + return ta; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::UpdateL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::UpdateL(CSIPMessageElements* aElements, + TUint* aExpirationValue) + { + __TEST_INVARIANT; + return StateL().UpdateL(*this, aElements, aExpirationValue); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DoUpdateL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::DoUpdateL(CSIPMessageElements* aElements, + TUint* aExpirationValue) + { + __TEST_INVARIANT; + CheckConnectionL(); + + CSIPClientTransaction* ta = CSIPClientTransaction::NewLC( + SIPStrings::StringF(SipStrConsts::ERegister), + *this); + + CSIPMessageElements* elem = aElements; + if (!aElements) + { + elem = CSIPMessageElements::NewLC(); + } + + if (aExpirationValue) + { + iContact->SetExpiresParameterL(*aExpirationValue); + } + + //Put contact temporarily to elem. Once REGISTER is sent, clear it from elem + CleanupStack::PushL(TCleanupItem(DetachContactHeader, elem)); + elem->AddHeaderL(iContact); + + TUint32 requestId(0); + iConnection->Implementation().ClientConnectionL().UpdateRegistrationL( + iRegistrationId, + requestId, + elem); + CleanupStack::PopAndDestroy(); //TCleanupItem + if (aElements) + { + delete aElements; + } + else + { + CleanupStack::PopAndDestroy(elem); + } + + CleanupStack::Pop(ta); + ta->SetRequestId(requestId); + + __TEST_INVARIANT; + return ta; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SetOutboundProxyL +// ----------------------------------------------------------------------------- +// +void +CRegBindingImplementation::SetOutboundProxyL(CSIPRouteHeader* aOutboundProxy) + { + __TEST_INVARIANT; + + if (IsContextActive()) + { + CheckConnectionL(); + + CSIPClientConnection& conn = + iConnection->Implementation().ClientConnectionL(); + if (aOutboundProxy) + { + conn.SetOutboundProxyL(iRegistrationId, *aOutboundProxy); + } + else + { + conn.RemoveOutboundProxy(iRegistrationId); + } + } + + //Remove old proxy when leave can not occur + delete iOutboundProxy; + iOutboundProxy = aOutboundProxy; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::Aor +// ----------------------------------------------------------------------------- +// +const CSIPToHeader& CRegBindingImplementation::Aor() const + { + __TEST_INVARIANT; + return *iAor; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ContactHeader +// ----------------------------------------------------------------------------- +// +const CSIPContactHeader& CRegBindingImplementation::ContactHeader() const + { + __TEST_INVARIANT; + return *iContact; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::RegisteredContact +// ----------------------------------------------------------------------------- +// +const CSIPContactHeader* CRegBindingImplementation::RegisteredContact() const + { + __TEST_INVARIANT; + return iRegisteredContact; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ContactHeader +// ----------------------------------------------------------------------------- +// +CSIPContactHeader& CRegBindingImplementation::ContactHeader() + { + __TEST_INVARIANT; + return *iContact; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::OutboundProxy +// ----------------------------------------------------------------------------- +// +const CSIPRouteHeader* CRegBindingImplementation::OutboundProxy() const + { + __TEST_INVARIANT; + return iOutboundProxy; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SIPRefresh +// ----------------------------------------------------------------------------- +// +const CSIPRefresh* CRegBindingImplementation::SIPRefresh() const + { + __TEST_INVARIANT; + return iRefresh; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SIPRefresh +// ----------------------------------------------------------------------------- +// +CSIPRefresh* CRegBindingImplementation::SIPRefresh() + { + __TEST_INVARIANT; + return iRefresh; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::Connection +// ----------------------------------------------------------------------------- +// +CSIPConnection* CRegBindingImplementation::Connection() + { + __TEST_INVARIANT; + return iConnection; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::Connection +// ----------------------------------------------------------------------------- +// +const CSIPConnection* CRegBindingImplementation::Connection() const + { + __TEST_INVARIANT; + return iConnection; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::IncomingResponseL +// ----------------------------------------------------------------------------- +// +TBool +CRegBindingImplementation::IncomingResponseL(CSIPResponseElements* aElements, + TUint32 aRequestId, + TUint32 aRegistrationId, + TUint32 aRefreshId, + CConnectionCallback& aCallback) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aElements != NULL, KErrArgument); + + if (iState) + { + return iState->IncomingResponseL(*this, + aElements, + aRequestId, + aRegistrationId, + aRefreshId, + aCallback); + } + delete aElements; + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ErrorOccured +// ----------------------------------------------------------------------------- +// +TBool CRegBindingImplementation::ErrorOccured(TInt aError, + TUint32 aRequestId, + CConnectionCallback& aCallback) + { + __TEST_INVARIANT; + return iState && iState->ErrorOccured(*this, aError, aRequestId, aCallback); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SetRegistrationId +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::SetRegistrationId(TUint32 aRegistrationId) + { + __TEST_INVARIANT; + + iRegistrationId = aRegistrationId; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::UpdateRefreshState +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::UpdateRefreshState(TUint aStatusCode) const + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN(iRefresh, KErrNotFound); + + iRefresh->UpdateRefreshState(aStatusCode); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::FindTransaction +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::FindTransaction(TUint32 aRequestId) + { + __TEST_INVARIANT; + + for (TInt i = 0; i < iTransactions.Count(); i++) + { + if (iTransactions[i]->RequestId() == aRequestId) + { + return iTransactions[i]; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ConnectionDeleted +// As CSIPClientConnection is deleted, SIP client stops all registrations. So no +// need to use TerminateRegistration. Clear iState as this object won't know +// when the CSIP owning the state handlers is deleted. +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::ConnectionDeleted() + { + __TEST_INVARIANT; + + iConnection = NULL; + iState = NULL; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::CheckConnectionL +// Don't use invariant here as CheckConnectionL is used from ConstructL. +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::CheckConnectionL() const + { + __ASSERT_ALWAYS(iConnection, User::Leave(KErrSIPResourceNotAvailable)); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::StateL +// ----------------------------------------------------------------------------- +// +const CRegistrationState& CRegBindingImplementation::StateL() const + { + __TEST_INVARIANT; + __ASSERT_ALWAYS(iState != NULL, User::Leave(KErrSIPResourceNotAvailable)); + + return *iState; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ClientConnectionL +// ----------------------------------------------------------------------------- +// +CSIPClientConnection& CRegBindingImplementation::ClientConnectionL() + { + __TEST_INVARIANT; + + CSIPClientConnection* clientConn = ClientConnection(); + __ASSERT_ALWAYS(clientConn, User::Leave(KErrSIPResourceNotAvailable)); + + return *clientConn; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ClientConnection +// ----------------------------------------------------------------------------- +// +CSIPClientConnection* CRegBindingImplementation::ClientConnection() + { + __TEST_INVARIANT; + + if (iConnection) + { + return iConnection->Implementation().ClientConnection(); + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SIPConnectionL +// ----------------------------------------------------------------------------- +// +CSIPConnection& CRegBindingImplementation::SIPConnectionL() + { + __TEST_INVARIANT; + CheckConnectionL(); + + return *iConnection; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ChangeState +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::ChangeState(const CRegistrationState* aNewState) + { + __TEST_INVARIANT; + + iState = aNewState; + + if (iRefresh) + { + if (iState) + { + iRefresh->ChangeState(iState->RefreshState()); + } + else + { + iRefresh->ChangeState(CSIPRefresh::ETerminated); + } + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::ConnectionLost +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::ConnectionLost() + { + __TEST_INVARIANT; + + if (iState) + { + iState->ConnectionLost(*this); + } + + for (TInt i = 0; i < iTransactions.Count(); i++) + { + iTransactions[i]->ChangeState(CSIPTransactionBase::ETerminated); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::operator== +// ----------------------------------------------------------------------------- +// +TBool CRegBindingImplementation::operator==( + const CRegBindingImplementation& aRegistration) const + { + __TEST_INVARIANT; + + return ( ContextId() && aRegistration.ContextId() && + (ContextId() == aRegistration.ContextId()) ) || + this == &aRegistration; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::Binding +// ----------------------------------------------------------------------------- +// +CSIPRegistrationBinding& CRegBindingImplementation::Binding() const + { + __TEST_INVARIANT; + return iRegistration; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::UpdateRegisteredContactL +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::UpdateRegisteredContactL() + { + CSIPContactHeader* contact = ClientConnectionL().ContactL(iRegistrationId); + delete iRegisteredContact; + iRegisteredContact = contact; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::RemoveRegisteredContact +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::RemoveRegisteredContact() + { + delete iRegisteredContact; + iRegisteredContact = NULL; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::UpdateRefreshL +// Application may not update or terminate a registration refresh. +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::UpdateRefreshL(CSIPRefresh& /*aRefresh*/, + CSIPMessageElements* /*aElements*/, + TBool /*aTerminate*/) + { + User::Leave(KErrSIPInvalidRegistrationState); + return NULL; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DeletingRefresh +// No need to use CSIPClientConnection::TerminateRefresh, as destructor calls +// TerminateRegistration freeing possible refresh from the SIP stack. +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::DeletingRefresh(CSIPRefresh& /*aRefresh*/, + TUint32 /*aRefreshId*/) + { + __TEST_INVARIANT; + + iRefresh = NULL; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::TransactionAssociation +// ----------------------------------------------------------------------------- +// +MTransactionAssociation& CRegBindingImplementation::TransactionAssociation() + { + __TEST_INVARIANT; + return *this; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::CheckIfStandAlone +// ----------------------------------------------------------------------------- +// +TInt CRegBindingImplementation::CheckIfStandAlone() + { + __TEST_INVARIANT; + return KErrSIPInvalidRegistrationState; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::AddTransactionL +// ----------------------------------------------------------------------------- +// +void +CRegBindingImplementation::AddTransactionL(CSIPTransactionBase& aTransaction) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aTransaction.IsSIPClientTransaction(), KErrArgument); + + /*lint -e826 */ + iTransactions.AppendL(static_cast(&aTransaction)); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::RemoveTransaction +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::RemoveTransaction( + const CSIPTransactionBase& aTransaction) + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN(aTransaction.IsSIPClientTransaction(), KErrArgument); + + /*lint -e826 */ + TInt pos = iTransactions.Find( + static_cast(&aTransaction)); + if (pos != KErrNotFound) + { + iTransactions.Remove(pos); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::CreateClientTransactionL +// ----------------------------------------------------------------------------- +// +CSIPClientTransaction* +CRegBindingImplementation::CreateClientTransactionL() + { + __TEST_INVARIANT; + return CSIPClientTransaction::NewL( + SIPStrings::StringF(SipStrConsts::ERegister), + *this, + iRefresh); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::HandleError +// ----------------------------------------------------------------------------- +// +TBool +CRegBindingImplementation::HandleError(CConnectionCallback& aCallback, + TInt aError, + TUint32 aRequestId, + const CRegistrationState& aUnregistered) + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN_VALUE(aError != KErrNone, EFalse); + + RemoveRegisteredContact(); + ChangeState(&aUnregistered); + + CConnectionCallback::TCallbackMethod callback = + CConnectionCallback::EErrorOccuredInRegistration; + CSIPClientTransaction* ta = FindTransaction(aRequestId); + if (ta) + { + ta->ChangeState(CSIPTransactionBase::ETerminated); + callback = + CConnectionCallback::EErrorOccuredInRegistrationWithTransaction; + } + + aCallback.Set(callback, ta, &Binding(), NULL, NULL, aError); + + __TEST_INVARIANT; + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::CheckElementsL +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::CheckElementsL( + const CSIPMessageElements* aElements) const + { + __TEST_INVARIANT; + + if (aElements) + { + RStringF contact = SIPStrings::StringF(SipStrConsts::EContactHeader); + RStringF expires = SIPStrings::StringF(SipStrConsts::EExpiresHeader); + + const RPointerArray& headers = aElements->UserHeaders(); + for (TInt i = 0; i < headers.Count(); i++) + { + if (headers[i]->Name() == contact || headers[i]->Name() == expires) + { + User::Leave(KErrSIPMalformedMessage); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DetachContactHeader +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::DetachContactHeader(TAny* aElements) + { + __SIP_ASSERT_RETURN(aElements, KErrArgument); + DetachHeaders(aElements, SIPStrings::StringF(SipStrConsts::EContactHeader)); + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::DetachHeaders +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::DetachHeaders(TAny* aElements, RStringF aName) + { + __SIP_ASSERT_RETURN(aElements, KErrArgument); + + CSIPMessageElements* elem = + reinterpret_cast(aElements); + const RPointerArray& headers = elem->UserHeaders(); + + for (TInt i = headers.Count() - 1; i >= 0; i--) + { + if (headers[i]->Name() == aName) + { + elem->DetachUserHeader(headers[i]); + } + } + } +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::SetPropertyL +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::SetPropertyL(TUint32 aProperty,TBool aValue) + { + __ASSERT_ALWAYS(!IsContextActive(), User::Leave(KErrSIPInvalidRegistrationState)); + switch(aProperty) + { + case KSIPSendWithExpires: + { + iSendWithExpires = aValue; + break; + } + case KSIPCacheOutboundProxyIP: + { + iCacheOutboundProxyIP = aValue; + break; + } + default: + User::Leave(KErrNotFound); + } + } + +// ----------------------------------------------------------------------------- +// CRegBindingImplementation::__DbgTestInvariant +// ----------------------------------------------------------------------------- +// +void CRegBindingImplementation::__DbgTestInvariant() const + { + if (!iContact || !iAor) + { + User::Invariant(); + } + }