diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/TransactionUser/src/InviteUAS.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/TransactionUser/src/InviteUAS.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,364 @@ +// 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 : InviteUAS.cpp +// Part of : TransactionUser +// Version : SIP/6.0 +// + + + +#include "siperr.h" +#include "sipinternalerr.h" +#include "SipAssert.h" +#include "sipresponse.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "MSipDialogs.h" +#include "TransactionMgr.h" +#include "Transmitter.h" + +#include "MTransactionOwner.h" +#include "InviteUAS.h" +#include "InviteServerTa.h" // Leave2xxForUAS +#include "SIPMessageUtility.h" +#include "CTransactionStore.h" +#include "UserAgentState.h" +#include "UserAgentTimer.h" +#include "TimerValues.h" + + +// ----------------------------------------------------------------------------- +// CInviteUAS::NewL +// ----------------------------------------------------------------------------- +// +CInviteUAS* CInviteUAS::NewL(CUserAgentCreateParams& aParams, + MSipConnectionMgr& aConnectionMgr, + MSIPRequestRouter& aRouter, + MSipDialogs& aDialogs) + { + CInviteUAS* self = new (ELeave) CInviteUAS(aParams, aDialogs, aRouter); + CleanupStack::PushL(self); + self->ConstructL(aConnectionMgr); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::CInviteUAS +// ----------------------------------------------------------------------------- +// +CInviteUAS::CInviteUAS(CUserAgentCreateParams& aParams, + MSipDialogs& aDialogs, + MSIPRequestRouter& aRouter) : + CUserAgentServer(aParams, aDialogs, aRouter) + { + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::ConstructL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::ConstructL(MSipConnectionMgr& aConnectionMgr) + { + CUserAgent::ConstructL(aConnectionMgr); + CreateTransactionL(); + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::~CInviteUAS +// Transaction must clear pointers to the 2xx, as UAS will delete the 2xx. +// ----------------------------------------------------------------------------- +// +CInviteUAS::~CInviteUAS() + { + CancelAllTimers(); + + if (IsSending2xx() && iTransaction && !iTransaction->HasTerminated()) + { + CInviteServerTransaction::Ptr(*iTransaction).Leave2xxForUAS(); + } + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::CreateTransactionL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::CreateTransactionL() + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(!iTransaction && iTransmitter, KErrAlreadyExists); + + iTransaction = iTransactionMgr.CreateTransactionL( + CTransactionBase::KServerInviteTransaction, + *this, + *iTransmitter, + iTimerValues); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::DoesDialogExistForAckL +// ----------------------------------------------------------------------------- +// +TBool CInviteUAS::DoesDialogExistForAckL(CSIPRequest& aAck) + { + __TEST_INVARIANT; + + CSIPResponse* resp(NULL); + MTransactionOwner* taOwner = iDialogs.TransactionOwnerL(aAck, &resp); + if (taOwner) + { + iObserver = taOwner; + return ETrue; + } + + // Nothing is sent after ACK + delete resp; + + __TEST_INVARIANT; + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::SendFirst2xxL +// Clear transaction from CTransactionStore, so further INVITEs/ACKs are passed +// to UAS, and not to transaction. INVITE UAS owns the 2xx. +// ----------------------------------------------------------------------------- +// +void CInviteUAS::SendFirst2xxL(CSIPResponse* aResp) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aResp, KErrArgument); + __SIP_ASSERT_LEAVE(aResp->Type() == CSIPResponse::E2XX, KErrArgument); + + iTransactionStore.ClearTransaction(TransactionId()); + StartTimerWaitAckL(); + SendResponseToTransactionL(aResp); + iOutgoingMsg = aResp; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::Retransmit2xxL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::Retransmit2xxL() + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(iOutgoingMsg && iTransmitter, KErrGeneral); + __SIP_ASSERT_LEAVE( + static_cast(iOutgoingMsg)->Type() == CSIPResponse::E2XX, + KErrSIPMalformedMessage); + + iTransmitter->SendResponseL(static_cast(*iOutgoingMsg), + TransportParams(), + this, + TransactionId()); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::CancelInviteL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::CancelInviteL() + { + __TEST_INVARIANT; + + if (!iCanceled) + { + iCanceled = State().CancelL(*this); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::HandleCancelInviteL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::HandleCancelInviteL(const CUserAgentState& aRejected) + { + __TEST_INVARIANT; + + if (iTransaction) + { + SendErrorResponseL(487, + SIPStrings::StringF(SipStrConsts::EPhraseRequestTerminated), + aRejected); + } + + if (!InformObserverAboutCancel()) + { + // Waiting to get MTransactionOwner. End silently. + CancelGetOwnerRequest(); + StopTimerOwnerResolver(); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::InformObserverAboutCancel +// ----------------------------------------------------------------------------- +// +TBool CInviteUAS::InformObserverAboutCancel() + { + if (iObserver) + { + // INVITE was passed to iObserver, run transaction silently to end + iObserver->TransactionEnded(iTransportParams.IapId(), + TransactionId(), + KInviteTransactionCancelled); + iObserver = NULL; + return ETrue; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::IsSending2xx +// ----------------------------------------------------------------------------- +// +TBool CInviteUAS::IsSending2xx() const + { + __TEST_INVARIANT; + return iOutgoingMsg && CSIPMessageUtility::Is2xxResponse(*iOutgoingMsg); + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::StartTimerRetransmit2xxL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::StartTimerRetransmit2xxL() + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(!iTimerRetransmit2xx, KErrAlreadyExists); + + iTimerValues.DoubleUptoT2(iTimerRetransmit2xxDuration); + iTimerRetransmit2xx = + CTimerRetransmit2xx::NewL(iTimers, + this, + iTimerRetransmit2xxDuration); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::StopTimerRetransmit2xx +// ----------------------------------------------------------------------------- +// +void CInviteUAS::StopTimerRetransmit2xx() + { + __TEST_INVARIANT; + + delete iTimerRetransmit2xx; + iTimerRetransmit2xx = NULL; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::StartTimerWaitAckL +// ----------------------------------------------------------------------------- +// +void CInviteUAS::StartTimerWaitAckL() + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(!iTimerWaitAck, KErrAlreadyExists); + + iTimerWaitAck = CTimerStopUA::NewL(iTimers, + this, + iTimerValues.Duration64xT1(), + KErrSIPNoAckReceived); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::StopTimerWaitAck +// ----------------------------------------------------------------------------- +// +void CInviteUAS::StopTimerWaitAck() + { + __TEST_INVARIANT; + + delete iTimerWaitAck; + iTimerWaitAck = NULL; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::DeleteTimer +// ----------------------------------------------------------------------------- +// +void CInviteUAS::DeleteTimer(const CUserAgentTimer& aTimer) + { + __TEST_INVARIANT; + + if (&aTimer == iTimerRetransmit2xx) + { + StopTimerRetransmit2xx(); + } + + if (&aTimer == iTimerWaitAck) + { + StopTimerWaitAck(); + } + + if (&aTimer == iTimerOwnerResolver) + { + StopTimerOwnerResolver(); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::CancelAllTimers +// ----------------------------------------------------------------------------- +// +void CInviteUAS::CancelAllTimers() + { + __TEST_INVARIANT; + + StopTimerRetransmit2xx(); + StopTimerWaitAck(); + StopTimerOwnerResolver(); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::Ptr +// ----------------------------------------------------------------------------- +// +CInviteUAS& CInviteUAS::Ptr(CUserAgent& aUserAgent) + { + return static_cast(aUserAgent); + } + +// ----------------------------------------------------------------------------- +// CInviteUAS::__DbgTestInvariant +// ----------------------------------------------------------------------------- +// + +void CInviteUAS::__DbgTestInvariant() const + { + if (iTimerRetransmit2xxDuration > iTimerValues.T2()) + { + User::Invariant(); + } + } +