realtimenetprots/sipfw/SIP/TransactionUser/src/InviteUAS.cpp
changeset 0 307788aac0a8
--- /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<CSIPResponse*>(iOutgoingMsg)->Type() == CSIPResponse::E2XX,
+        KErrSIPMalformedMessage);
+
+	iTransmitter->SendResponseL(static_cast<CSIPResponse&>(*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<CInviteUAS&>(aUserAgent);
+	}
+
+// -----------------------------------------------------------------------------
+// CInviteUAS::__DbgTestInvariant
+// -----------------------------------------------------------------------------
+//
+
+void CInviteUAS::__DbgTestInvariant() const
+	{
+	if (iTimerRetransmit2xxDuration > iTimerValues.T2())
+		{	
+		User::Invariant();
+		}
+	}
+