diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/TransactionUser/src/CTransactionUser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/TransactionUser/src/CTransactionUser.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,875 @@ +// 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 : CTransactionUser.cpp +// Part of : TransactionUser +// Version : SIP/6.0 +// + + + +#include "siperr.h" +#include "SipAssert.h" +#include "siprequest.h" +#include "sipresponse.h" +#include "sipsec.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "TransactionMgr.h" + +#include "CTransactionUser.h" +#include "CTransactionStore.h" +#include "DeleteMgr.h" +#include "NormalUAC.h" +#include "InviteUAC.h" +#include "CancelUAC.h" +#include "NormalUAS.h" +#include "InviteUAS.h" +#include "CancelUAS.h" +#include "NormalUACStates.h" +#include "InviteUACStates.h" +#include "CancelUACStates.h" +#include "NormalUASStates.h" +#include "InviteUASStates.h" +#include "CancelUASStates.h" +#include "UserAgentCreateParams.h" +#include "TimerValueRetriever.h" +#include "SIPMessageUtility.h" +#include "MTransactionHeaders.h" + +using namespace CommsDat; + +// CSeq sequence number is a 32 bit integer, and must be less than 2**31 +const TUint32 KMaxCSeqValue = 0x7fffffff; + + +// ----------------------------------------------------------------------------- +// CTransactionUser::NewL +// ----------------------------------------------------------------------------- +// +CTransactionUser* CTransactionUser::NewL(MSIPRequestRouter* aRouter, + MTimerManager* aTimers, + MConnectionStateObserver& aObserver) + { + __SIP_ASSERT_LEAVE(aRouter && aTimers, KErrArgument); + + CTransactionUser* self = new (ELeave) CTransactionUser(aRouter, + aTimers, + aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::CTransactionUser +// ----------------------------------------------------------------------------- +// +CTransactionUser::CTransactionUser(MSIPRequestRouter* aRouter, + MTimerManager* aTimers, + MConnectionStateObserver& aStateObserver) : + iRouter(aRouter), + iTimers(aTimers), + iStateObserver(aStateObserver) + { + iCSeqCounter = User::TickCount() & KMaxCSeqValue; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::ConstructL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::ConstructL() + { + __SIP_ASSERT_LEAVE(iTimers, KErrGeneral); + + iTransactionStore = CTransactionStore::NewL(); + iTimerValueRetriever = CTimerValueRetriever::NewL(); + TUint t1 = iTimerValueRetriever->HighestT1(); + iConnectionMgr = CSipConnectionMgr::NewL(*iTransactionStore, + *this, + *iTimers, + t1, + *this); + iDeleteMgr = CDeleteMgr::NewL(); + iSIPMsgUtility = new (ELeave) CSIPMessageUtility; + + ConstructUaStateMachinesL(); + + iTransactionMgr = CTransactionMgr::NewL(*iTimers, *iTransactionStore); + iSIPSec = CSIPSec::NewL(*iTimers, *iConnectionMgr, t1); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::ConstructUaStateMachinesL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::ConstructUaStateMachinesL() + { + iInviteUAC_Start = new (ELeave) CInviteUAC_Start; + iInviteUAC_ResolveAddress = new (ELeave) CInviteUAC_ResolveAddress; + iInviteUAC_WaitResponse = new (ELeave) CInviteUAC_WaitResponse; + iInviteUAC_WaitAckFromApp = new (ELeave) CInviteUAC_WaitAckFromApp; + iInviteUAC_ResolveAckAddress = new (ELeave) CInviteUAC_ResolveAckAddress; + iInviteUAC_SendingAck = new (ELeave) CInviteUAC_SendingAck; + iInviteUAC_WaitTransactionToEnd = + new (ELeave) CInviteUAC_WaitTransactionToEnd; + iInviteUAC_WaitAuthentication = new (ELeave) CInviteUAC_WaitAuthentication; + + iInviteUAC_Start->SetNeighbourStates(*iInviteUAC_ResolveAddress); + iInviteUAC_ResolveAddress->SetNeighbourStates(*iInviteUAC_WaitResponse); + iInviteUAC_WaitResponse->SetNeighbourStates( + *iInviteUAC_WaitAckFromApp, + *iInviteUAC_WaitTransactionToEnd, + *iInviteUAC_ResolveAddress, + *iInviteUAC_WaitAuthentication); + iInviteUAC_WaitAckFromApp->SetNeighbourStates( + *iInviteUAC_ResolveAckAddress); + iInviteUAC_ResolveAckAddress->SetNeighbourStates(*iInviteUAC_SendingAck); + iInviteUAC_SendingAck->SetNeighbourStates(*iInviteUAC_ResolveAckAddress); + iInviteUAC_WaitAuthentication->SetNeighbourStates( + *iInviteUAC_ResolveAddress, + *iInviteUAC_WaitResponse, + *iInviteUAC_WaitAckFromApp, + *iInviteUAC_WaitTransactionToEnd); + + + iNormalUAC_Start = new (ELeave) CNormalUAC_Start; + iNormalUAC_ResolveAddress = new (ELeave) CNormalUAC_ResolveAddress; + iNormalUAC_WaitResponse = new (ELeave) CNormalUAC_WaitResponse; + iNormalUAC_WaitAuthentication = new (ELeave) CNormalUAC_WaitAuthentication; + + iNormalUAC_Start->SetNeighbourStates(*iNormalUAC_ResolveAddress); + iNormalUAC_ResolveAddress->SetNeighbourStates(*iNormalUAC_WaitResponse); + iNormalUAC_WaitResponse->SetNeighbourStates(*iNormalUAC_ResolveAddress, + *iNormalUAC_WaitAuthentication); + iNormalUAC_WaitAuthentication->SetNeighbourStates( + *iNormalUAC_ResolveAddress, + *iNormalUAC_WaitResponse); + + + iCancelUAC_Start = new (ELeave) CCancelUAC_Start; + // CancelUAC uses rest of NormalUAC's states + iCancelUAC_Start->SetNeighbourStates(*iNormalUAC_WaitResponse); + + + iInviteUAS_Start = new (ELeave) CInviteUAS_Start; + iInviteUAS_GetTxOwner = new (ELeave) CInviteUAS_GetTxOwner; + iInviteUAS_WaitRespFromApp = new (ELeave) CInviteUAS_WaitRespFromApp; + iInviteUAS_Accepted = new (ELeave) CInviteUAS_Accepted; + iInviteUAS_Rejected = new (ELeave) CInviteUAS_Rejected; + + iInviteUAS_Start->SetNeighbourStates(*iInviteUAS_GetTxOwner, + *iInviteUAS_WaitRespFromApp, + *iInviteUAS_Rejected); + iInviteUAS_GetTxOwner->SetNeighbourStates(*iInviteUAS_WaitRespFromApp, + *iInviteUAS_Rejected); + iInviteUAS_WaitRespFromApp->SetNeighbourStates(*iInviteUAS_Accepted, + *iInviteUAS_Rejected); + + + iNormalUAS_Start = new (ELeave) CNormalUAS_Start; + iNormalUAS_GetTxOwner = new (ELeave) CNormalUAS_GetTxOwner; + iNormalUAS_WaitRespFromApp = new (ELeave) CNormalUAS_WaitRespFromApp; + iNormalUAS_FinalRespSent = new (ELeave) CNormalUAS_FinalRespSent; + + iNormalUAS_Start->SetNeighbourStates(*iNormalUAS_GetTxOwner, + *iNormalUAS_WaitRespFromApp, + *iNormalUAS_FinalRespSent); + iNormalUAS_GetTxOwner->SetNeighbourStates(*iNormalUAS_WaitRespFromApp, + *iNormalUAS_FinalRespSent); + iNormalUAS_WaitRespFromApp->SetNeighbourStates(*iNormalUAS_FinalRespSent); + + + iCancelUAS_Start = new (ELeave) CCancelUAS_Start; + iCancelUAS_FinalRespSent = new (ELeave) CCancelUAS_FinalRespSent; + + iCancelUAS_Start->SetNeighbourStates(*iCancelUAS_FinalRespSent); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::~CTransactionUser +// Deleting iTransactionStore and iDeleteMgr can lead deleting CTransmitter +// (cancels request to iConnectionMgr) and UAC (cancels request to SIPSec). +// ----------------------------------------------------------------------------- +// +CTransactionUser::~CTransactionUser() + { + delete iTransactionStore; + delete iDeleteMgr; + delete iTransactionMgr; + delete iTimerValueRetriever; + delete iConnectionMgr; + delete iSIPMsgUtility; + delete iSIPSec; + + delete iInviteUAC_Start; + delete iInviteUAC_ResolveAddress; + delete iInviteUAC_WaitResponse; + delete iInviteUAC_WaitAckFromApp; + delete iInviteUAC_ResolveAckAddress; + delete iInviteUAC_SendingAck; + delete iInviteUAC_WaitTransactionToEnd; + delete iInviteUAC_WaitAuthentication; + + delete iNormalUAC_Start; + delete iNormalUAC_ResolveAddress; + delete iNormalUAC_WaitResponse; + delete iNormalUAC_WaitAuthentication; + + delete iCancelUAC_Start; + + delete iInviteUAS_Start; + delete iInviteUAS_GetTxOwner; + delete iInviteUAS_WaitRespFromApp; + delete iInviteUAS_Accepted; + delete iInviteUAS_Rejected; + + delete iNormalUAS_Start; + delete iNormalUAS_GetTxOwner; + delete iNormalUAS_WaitRespFromApp; + delete iNormalUAS_FinalRespSent; + + delete iCancelUAS_Start; + delete iCancelUAS_FinalRespSent; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SIPSec +// ----------------------------------------------------------------------------- +// +CSIPSec& CTransactionUser::SIPSec() + { + return *iSIPSec; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SipConnectionMgr +// ----------------------------------------------------------------------------- +// +CSipConnectionMgr& CTransactionUser::SipConnectionMgr() + { + return *iConnectionMgr; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SetDialogs +// No invariant as iDialogs/iRegistrations/iRegistrationContact aren't set yet. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SetDialogs(MSipDialogs* aDialogs) + { + __SIP_ASSERT_RETURN(aDialogs, KErrArgument); + + iDialogs = aDialogs; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SetRegistrations +// No invariant as iDialogs/iRegistrations/iRegistrationContact aren't set yet. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SetRegistrations( + MSipRegistrations* aRegistrations, + MSipRegistrationContact* aRegistrationContact) + { + __SIP_ASSERT_RETURN(aRegistrations && aRegistrationContact, KErrArgument); + + iRegistrations = aRegistrations; + iRegistrationContact = aRegistrationContact; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::GetStateL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::GetStateL(TTransactionId aTransactionId, + CSIPInternalStates::TState& aState) const + { + __TEST_INVARIANT; + + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + __ASSERT_ALWAYS(ua && ua->Transaction(), User::Leave(KErrNotFound)); + ua->Transaction()->GetState(aState); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::NewCSeqValue +// ----------------------------------------------------------------------------- +// +TUint32 CTransactionUser::NewCSeqValue() + { + __TEST_INVARIANT; + + if (iCSeqCounter >= KMaxCSeqValue) + { + iCSeqCounter = 0; + } + + return ++iCSeqCounter; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SendL +// Send ACK using an existing INVITE-UAC. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SendL(TTransactionId& aTransactionId, + TRegistrationId aRegistrationId, + CSIPRequest* aRequest, + MTransactionOwner* aObserver, + CURIContainer& aRemoteTarget, + const TSIPTransportParams& aTransportParams, + TBool aDeleteRequest) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRequest && aObserver, KErrArgument); + __SIP_MESSAGE_LOG("TransactionUser", *aRequest) + + if (CSIPMessageUtility::IsAck(*aRequest)) + { + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + __ASSERT_ALWAYS(ua && ua->IsInviteUAC(), + User::Leave(KErrSIPInvalidTransactionState)); + CInviteUAC::Ptr(*ua).SendAckL(aRequest, + *aObserver, + aTransportParams, + aRegistrationId, + aRemoteTarget, + aDeleteRequest, + SIPStrings::StringF(SipStrConsts::EEmpty)); + } + else + { + CTransactionBase::TTransactionType type = + CTransactionBase::KClientTransaction; + if (aRequest->Method() == SIPStrings::StringF(SipStrConsts::EInvite)) + { + type = CTransactionBase::KClientInviteTransaction; + } + + aTransactionId = iTransactionStore->NewTransactionId(); + CUserAgent* ua = CreateUacL(aTransactionId, + aRequest->Method(), + *aObserver, + aDeleteRequest, + NewCSeqValue(), + aTransportParams); + TCleanupItem cleanupItem(CUserAgent::CleanupSilently, ua); + CleanupStack::PushL(cleanupItem); + iTransactionStore->AddL(aTransactionId, ua, NULL, NULL, type); + ua->SendRequestL(aRequest, aRegistrationId, aRemoteTarget); + CleanupStack::Pop(); // cleanupItem + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SendAndGetHeadersL +// ----------------------------------------------------------------------------- +// +MTransactionHeaders* +CTransactionUser::SendAndGetHeadersL(TTransactionId& aTransactionId, + TRegistrationId aRegistrationId, + CSIPRequest* aRequest, + MTransactionOwner* aObserver, + CURIContainer& aRemoteTarget, + const TSIPTransportParams& aTransportParams, + TBool aDeleteRequest) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRequest && aObserver, KErrArgument); + + SendL(aTransactionId, + aRegistrationId, + aRequest, + aObserver, + aRemoteTarget, + aTransportParams, + EFalse); // Don't take aRequest's ownership yet as leave can occur + + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + __SIP_ASSERT_LEAVE(ua, KErrNotFound); + + TCleanupItem cleanupItem(CUserAgent::CleanupSilently, ua); + CleanupStack::PushL(cleanupItem); + MTransactionHeaders* headers = + iTransactionStore->TransactionHeadersL(aTransactionId); + CleanupStack::Pop(); // cleanupItem + + static_cast(ua)->SetRequestOwnership(aDeleteRequest); + + __TEST_INVARIANT; + return headers; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SendL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SendL(TTransactionId aTransactionId, + CSIPResponse* aResp, + const TSIPTransportParams& aTransportParams) const + { + __TEST_INVARIANT; + + SendL(aTransactionId, aResp, NULL, aTransportParams); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SendL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SendL(TTransactionId aTransactionId, + CSIPResponse* aResp, + MTransactionOwner* aNewObserver, + const TSIPTransportParams& aTransportParams) const + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aTransactionId != KEmptyTransactionId, KErrArgument); + __SIP_ASSERT_LEAVE(aResp, KErrArgument); + __SIP_MESSAGE_LOG("TransactionUser", *aResp) + + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + __ASSERT_ALWAYS(ua && ua->IsUAS(), + User::Leave(KErrSIPInvalidTransactionState)); + if (aNewObserver) + { + ua->UpdateTransactionOwner(aNewObserver); + } + + ua->SendResponseL(aResp, aTransportParams); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::SendCancelL +// CANCEL uses INVITE's TransportParams. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::SendCancelL(TTransactionId aInviteTaId, + TTransactionId& aCancelTaId, + MTransactionOwner* aObserver) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aObserver, KErrArgument); + + CUserAgent* ua = iTransactionStore->SearchById(aInviteTaId); + __ASSERT_ALWAYS(ua && + ua->Transaction() && + iTransactionMgr->IsPossibleToSendCancel(*ua->Transaction()), + User::Leave(KErrSIPInvalidTransactionState)); + aCancelTaId = iTransactionStore->NewTransactionId(); + CCancelUAC* cancelUa = CreateCancelUacL(aCancelTaId, + *aObserver, + NewCSeqValue(), + ua->TransportParams()); + TCleanupItem cleanupItem(CUserAgent::CleanupSilently, cancelUa); + CleanupStack::PushL(cleanupItem); + iTransactionStore->AddL(aCancelTaId, + cancelUa, + NULL, + NULL, + CTransactionBase::KClientTransaction); + cancelUa->SendCancelL(aInviteTaId); + CleanupStack::Pop(); // cleanupItem + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::ClearTransactionOwner +// ----------------------------------------------------------------------------- +// +TInt +CTransactionUser::ClearTransactionOwner(TTransactionId aTransactionId) const + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN_VALUE(aTransactionId != KEmptyTransactionId, + KErrArgument); + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + if (ua) + { + ua->ClearTransactionOwner(); + return KErrNone; + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::ClearTransactionOwner +// ----------------------------------------------------------------------------- +// +TInt CTransactionUser::ClearTransactionOwner(MTransactionOwner* aObserver) const + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN_VALUE(aObserver, KErrArgument); + + return iTransactionStore->ClearTransactionOwner(aObserver); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::TransactionHeadersL +// ----------------------------------------------------------------------------- +// +MTransactionHeaders* +CTransactionUser::TransactionHeadersL(TTransactionId aTransactionId) const + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aTransactionId != KEmptyTransactionId, KErrArgument); + + return iTransactionStore->TransactionHeadersL(aTransactionId); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::MakeTagL +// ----------------------------------------------------------------------------- +// +void CTransactionUser::MakeTagL(TDes8& aTag) const + { + __TEST_INVARIANT; + __ASSERT_ALWAYS(aTag.Length() != aTag.MaxLength(), + User::Leave(KErrArgument)); + TTransactionId taId = KEmptyTransactionId; + CUserAgent* ua = NULL; + CSIPMessage* message = NULL; + iTransactionStore->RandomTaInfoL(taId, &ua, &message); + + CleanupStack::PushL(message); + iSIPMsgUtility->AddRandomStringL(aTag, + aTag.MaxLength() - aTag.Length(), + EFalse, + message, + taId, + ua); + CleanupStack::PopAndDestroy(message); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::NewTransactionL +// ----------------------------------------------------------------------------- +// +MReceiverObserver* +CTransactionUser::NewTransactionL(CSIPRequest& aRequest, + const TSIPTransportParams& aParams, + TTransactionId& aTransactionId) + { + __TEST_INVARIANT; + + if (CSIPMessageUtility::IsAck(aRequest) || + !iTransactionStore->AllowMoreServerTransactions()) + { + return NULL; + } + + aTransactionId = iTransactionStore->NewTransactionId(); + CUserAgent* ua = CreateUasL(aTransactionId, aRequest.Method(), aParams); + MReceiverObserver* receiver = ua->Transaction(); + + CleanupStack::PushL(ua); + iTransactionStore->AddL(aTransactionId, + ua, + ua->Transaction(), + &aRequest, + CSIPMessageUtility::TransactionType(aRequest, ETrue)); + CleanupStack::Pop(ua); + + __TEST_INVARIANT; + return receiver; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::FillUserAgentParamsLC +// ----------------------------------------------------------------------------- +// +CUserAgentCreateParams* +CTransactionUser::FillUserAgentParamsLC(TTransactionId aTransactionId, + MTransactionOwner* aObserver, + TBool aDeleteOutgoingMsg, + const TSIPTransportParams& aParams) const + { + __TEST_INVARIANT; + CTimerValueRetriever::BearerType bearerType = + (CTimerValueRetriever::BearerType)TimerRetrieverMappedBearerTypeL(aParams.IapId()); + CUserAgentCreateParams* uaParams = + CUserAgentCreateParams::NewLC(*iTransactionMgr, + *iTimers, + *iSIPMsgUtility, + iTimerValueRetriever->TimerValues(bearerType), + *iRegistrations, + *iRegistrationContact, + *iConnectionMgr, + *iTransactionStore, + *iDeleteMgr, + aDeleteOutgoingMsg, + aParams); + uaParams->iTransactionId = aTransactionId; + uaParams->iObserver = aObserver; + + return uaParams; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::CreateUasL +// ----------------------------------------------------------------------------- +// +CUserAgent* CTransactionUser::CreateUasL(TTransactionId aTaId, + RStringF aMethod, + const TSIPTransportParams& aParams) const + { + __TEST_INVARIANT; + + CUserAgent* ua = NULL; + CUserAgentCreateParams* uaParams = + FillUserAgentParamsLC(aTaId, + NULL, // Observer not yet known + ETrue, // UAS sends responses + aParams); + if (aMethod == SIPStrings::StringF(SipStrConsts::EInvite)) + { + uaParams->iInitialUaState = iInviteUAS_Start; + ua = CInviteUAS::NewL(*uaParams, *iConnectionMgr, *iRouter, *iDialogs); + } + else + { + if (aMethod == SIPStrings::StringF(SipStrConsts::ECancel)) + { + uaParams->iInitialUaState = iCancelUAS_Start; + ua = CCancelUAS::NewL(*uaParams, + *iConnectionMgr, + *iRouter, + *iDialogs); + } + else + { + uaParams->iInitialUaState = iNormalUAS_Start; + ua = CNormalUAS::NewL(*uaParams, + *iConnectionMgr, + *iRouter, + *iDialogs); + } + } + CleanupStack::PopAndDestroy(uaParams); + return ua; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::CreateUacL +// ----------------------------------------------------------------------------- +// +CUserAgent* CTransactionUser::CreateUacL(TTransactionId aTaId, + RStringF aMethod, + MTransactionOwner& aObserver, + TBool aDeleteRequest, + TUint32 aCSeqNumber, + const TSIPTransportParams& aParams) const + { + __TEST_INVARIANT; + + CUserAgent* ua = NULL; + CUserAgentCreateParams* uaParams = FillUserAgentParamsLC(aTaId, + &aObserver, + aDeleteRequest, + aParams); + if (aMethod == SIPStrings::StringF(SipStrConsts::EInvite)) + { + uaParams->iInitialUaState = iInviteUAC_Start; + ua = CInviteUAC::NewL(*uaParams, + *iConnectionMgr, + *iConnectionMgr, + *iSIPSec, + aCSeqNumber, + CSIPMessageUtility::IsPrivateAddressL( + *iConnectionMgr, aParams.IapId()), + iInviteUAC_WaitAckFromApp); + } + else + { + uaParams->iInitialUaState = iNormalUAC_Start; + ua = CNormalUAC::NewL(*uaParams, + *iConnectionMgr, + *iConnectionMgr, + *iSIPSec, + aCSeqNumber); + } + + CleanupStack::PopAndDestroy(uaParams); + return ua; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::CreateCancelUacL +// ----------------------------------------------------------------------------- +// +CCancelUAC* CTransactionUser::CreateCancelUacL(TTransactionId aTaId, + MTransactionOwner& aObserver, + TUint32 aCSeqNumber, + const TSIPTransportParams& aParams) const + { + __TEST_INVARIANT; + + CUserAgentCreateParams* uaParams = FillUserAgentParamsLC(aTaId, + &aObserver, + ETrue, + aParams); + uaParams->iInitialUaState = iCancelUAC_Start; + + CCancelUAC* ua = CCancelUAC::NewL(*uaParams, + *iConnectionMgr, + *iConnectionMgr, + *iSIPSec, + aCSeqNumber); + CleanupStack::PopAndDestroy(uaParams); + return ua; + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::GetLocalAddress +// No invariant as iDialogs/iRegistrations/iRegistrationContact aren't set yet. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::GetLocalAddress(TUint32 aIapId, TInetAddr& aAddr) const + { + __SIP_ASSERT_RETURN(iConnectionMgr, KErrGeneral); + + iConnectionMgr->GetLocalAddress(aIapId, aAddr); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::FreeResources +// No invariant as iDialogs/iRegistrations/iRegistrationContact aren't set yet. +// ----------------------------------------------------------------------------- +// +void +CTransactionUser::FreeResources(MSIPNATBindingObserver& aSIPNATBindingObserver) + { + __SIP_ASSERT_RETURN(iConnectionMgr, KErrGeneral); + + iConnectionMgr->FreeResources(aSIPNATBindingObserver); + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::ConnectionStateChangedL +// EInit/EActive: no action. If application opens an IAP that has been opened by +// another application, ConnectionMgr passes connection's current state. +// No invariant as iDialogs/iRegistrations/iRegistrationContact aren't set yet. +// ----------------------------------------------------------------------------- +// +void CTransactionUser::ConnectionStateChangedL(TUint32 aIapId, + CSIPConnection::TState aState) + { + __SIP_ASSERT_LEAVE(iTransactionStore, KErrGeneral); + + iStateObserver.ConnectionStateChangedL(aIapId, aState); + + switch (aState) + { + case CSIPConnection::ESuspended: + iTransactionStore->EndResolvingTransactions(aIapId, + KErrSIPTransportFailure); + break; + + case CSIPConnection::EInactive: + case CSIPConnection::EUnavailable: + iTransactionStore->RemoveItemsByIapId(aIapId); + break; + + default: + break; + } + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::TimerRetrieverMappedBearerType +// ----------------------------------------------------------------------------- +// +TInt CTransactionUser::TimerRetrieverMappedBearerTypeL(TUint32 aIapID) const +{ + CTimerValueRetriever::BearerType mappedBearerType(CTimerValueRetriever::EModemBearer); + + if (aIapID) + { + CMDBSession* cdb = CMDBSession::NewLC( KCDVersion1_1 ); + + cdb->SetAttributeMask( ECDHidden ); + + // Create an iap record + CCDIAPRecord* iapRecord = static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); + CleanupStack::PushL( iapRecord ); + + iapRecord->SetRecordId( aIapID ); + + iapRecord->LoadL( *cdb ); + + if (!iapRecord->iBearerType.IsNull()) + { + TPtrC bearerType(iapRecord->iBearerType); + if(bearerType.CompareF(TPtrC(KCDTypeNameLANBearer)) == 0) + mappedBearerType = CTimerValueRetriever::ELanBearer; + } + + + CleanupStack::PopAndDestroy( iapRecord ); + CleanupStack::PopAndDestroy( cdb ); + } + + return mappedBearerType; +} + +// ----------------------------------------------------------------------------- +// CTransactionUser::NextHopIP +// ----------------------------------------------------------------------------- +// +TInt CTransactionUser::NextHopIP( + const TTransactionId& aTransactionId, TInetAddr& aAddr ) + { + TInt error = KErrNone; + + CUserAgent* ua = iTransactionStore->SearchById(aTransactionId); + if (!ua || ua->IsUAS()) + { + error = CSIPClient::ENonExistingRequestId; + } + else + { + aAddr = static_cast(ua)->NextHopIP(); + } + + return error; + + } + +// ----------------------------------------------------------------------------- +// CTransactionUser::__DbgTestInvariant +// ----------------------------------------------------------------------------- +// + +void CTransactionUser::__DbgTestInvariant() const + { + if (!iRouter || + !iTimers || + !iTransactionStore || + !iConnectionMgr || + !iDialogs || + !iRegistrations || + !iRegistrationContact || + !iDeleteMgr || + !iTimerValueRetriever || + iCSeqCounter > KMaxCSeqValue) + { + User::Invariant(); + } + }