realtimenetprots/sipfw/SIP/sipapi/src/siptransactionbase.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/sipapi/src/siptransactionbase.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,333 @@
+// Copyright (c) 2005-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          : SIPTransactionBase.cpp
+// Part of       : SIPAPI
+// Version       : SIP/4.0 
+//
+
+
+
+#include "sip.h"
+#include "SipImplementation.h"
+#include "sipconnection.h"
+#include "sipclient.h"
+#include "siperr.h"
+#include "SipAssert.h"
+#include "siptransactionbase.h"
+#include "transactionassociation.h"
+#include "sipresponseelements.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "sipinternalstates.h"
+#include "sipclientserver.h"
+
+#ifdef CPPUNIT_TEST
+#undef EXPORT_C
+#define EXPORT_C
+#endif
+
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::CSIPTransactionBase
+// -----------------------------------------------------------------------------
+//
+CSIPTransactionBase::CSIPTransactionBase(TBool aIsClientTransaction,
+                                     TUint32 aRequestId,
+                                     MTransactionAssociation& aAssociation) :
+    iRequestId(aRequestId),
+    iAssociation(&aAssociation),    
+    iIsClientTransaction(aIsClientTransaction),
+    iState(EConstructing),
+    iAffectsDialogState(EFalse)
+	{	
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::ConstructL(RStringF aType)
+    {
+    SIPStrings::OpenL();
+    iState = ETrying;
+    iType = aType.Copy();
+
+    if (iType == SIPStrings::StringF(SipStrConsts::EInvite))
+        {
+        if (iIsClientTransaction)
+            {
+            iState = ECalling;
+            }
+        else
+            {
+            iState = EProceeding;
+            }
+        }
+
+    iAssociation->AddTransactionL(*this);
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::~CSIPTransactionBase
+// -----------------------------------------------------------------------------
+//
+CSIPTransactionBase::~CSIPTransactionBase()
+	{
+    delete iResponseElements;
+
+    if (iAssociation)
+        {
+        iAssociation->RemoveTransaction(*this);
+        }
+    iType.Close();
+  
+    if (iState != EConstructing)
+    	{
+    	SIPStrings::Close();
+    	}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::Type
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RStringF CSIPTransactionBase::Type() const
+    {
+    __TEST_INVARIANT;
+    return iType;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::State
+// If the current state is Completed or Confirmed, it is possible that the
+// transaction in the SIP server has entered another state, as some state
+// transitions happen without SIP Client API being aware of them.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPTransactionBase::TState CSIPTransactionBase::StateL()
+    {
+    __TEST_INVARIANT;
+
+    if (iState == ECompleted || iState == EConfirmed)
+    	{
+    	CheckAssociationL();
+
+    	RSIP& rsip = iAssociation->SIPConnectionL().SIP()->Implementation().
+    		SIPClient().SIP();
+    	CSIPInternalStates::TState
+    		state(CSIPInternalStates::ETransactionTrying);
+
+		TSIPIds ids;
+    	ids.iRequestId = iRequestId;
+    	CSIPInternalStates::GetState(rsip,
+	    							 ids,
+	    							 state,
+	    							 ESipItcGetTransactionState);
+    	//Convert state value. Only confirmed and terminated are needed.
+    	if (state == CSIPInternalStates::ETransactionConfirmed)
+    		{    		
+    		iState = EConfirmed;
+    		}
+    	else
+    		{
+    		if (state == CSIPInternalStates::ETransactionTerminated)
+    			{
+    			iState = ETerminated;
+    			}
+    		}
+    	
+    	}
+
+    return iState;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::IsSIPClientTransaction
+// Don't call __TEST_INVARIANT here.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPTransactionBase::IsSIPClientTransaction() const
+    {    
+    return iIsClientTransaction;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::operator==
+// Don't call __TEST_INVARIANT here.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool
+CSIPTransactionBase::operator==(const CSIPTransactionBase& aTransaction) const
+    {    
+    if (!iRequestId || !aTransaction.RequestId())
+        {
+        //If either of the ids is empty, the transactions are not considered
+        //same, unless their addresses are same
+        return this == &aTransaction;
+        }
+
+    return iRequestId == aTransaction.RequestId();    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::RequestId
+// -----------------------------------------------------------------------------
+//
+TUint32 CSIPTransactionBase::RequestId() const
+    {
+    __TEST_INVARIANT;
+    return iRequestId;    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::Detach
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::Detach(const MTransactionAssociation& aAssociation)
+    {
+    __SIP_ASSERT_RETURN(iAssociation != NULL, KErrNotFound);
+    __ASSERT_DEBUG(&aAssociation == iAssociation,
+		User::Panic(_L("CSIPTransactionBase::Detach() aAssoc != iAssoc"),
+		KErrArgument));
+
+    if (&aAssociation == iAssociation)
+        {
+        iAssociation = NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::CheckAssociationL
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::CheckAssociationL() const
+    {
+    if (!iAssociation)
+        {
+        User::Leave(KErrSIPResourceNotAvailable);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::ChangeState
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::ChangeState(CSIPTransactionBase::TState aNextState)
+    {
+    __TEST_INVARIANT;
+    __ASSERT_DEBUG(iAssociation != NULL,
+        User::Panic(_L("CSIPTransactionBase::ChangeState() iAssociation = 0"),
+        			KErrSIPResourceNotAvailable));
+
+    iState = aNextState;
+
+    __TEST_INVARIANT;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::SetResponseElements
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::SetResponseElements(CSIPResponseElements* aElements)
+    {
+    __TEST_INVARIANT;
+    __SIP_ASSERT_RETURN(aElements, KErrArgument);
+
+    delete iResponseElements;
+    iResponseElements = aElements;
+
+    TUint statusCode = iResponseElements->StatusCode();
+    if (statusCode < 200 || statusCode == 401 || statusCode == 407)
+        {
+        ChangeState(EProceeding);
+        }
+    else
+        {
+        if (iType == SIPStrings::StringF(SipStrConsts::EInvite) &&
+            iResponseElements->StatusCode() < 300)
+            {
+            ChangeState(ETerminated);
+            }
+        else
+            {
+            ChangeState(ECompleted);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::AffectsDialogState
+// -----------------------------------------------------------------------------
+//
+TBool CSIPTransactionBase::AffectsDialogState() const
+    {
+    __TEST_INVARIANT;
+    __ASSERT_DEBUG(iAssociation != NULL,
+        User::Panic(_L("CSIPTaBase::AffectsDialogState() iAssociation = 0"),
+        			KErrSIPResourceNotAvailable));
+
+    return iAffectsDialogState;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::SetAffectsDialogState
+// -----------------------------------------------------------------------------
+//
+void CSIPTransactionBase::SetAffectsDialogState()
+    {
+    __TEST_INVARIANT;    
+    __SIP_ASSERT_RETURN(!iAffectsDialogState, KErrNotFound);
+    __ASSERT_DEBUG(iAssociation != NULL,
+        User::Panic(_L("CSIPTaBase::SetAffectsDialogState() iAssociation = 0"),
+        			KErrSIPResourceNotAvailable));
+    
+    iAffectsDialogState = ETrue;
+
+    __TEST_INVARIANT;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::IsTargetRefresh
+// -----------------------------------------------------------------------------
+//
+TBool CSIPTransactionBase::IsTargetRefresh(RStringF aType)
+    {
+    return (aType == SIPStrings::StringF(SipStrConsts::EInvite) ||
+        	aType == SIPStrings::StringF(SipStrConsts::EUpdate) ||
+        	aType == SIPStrings::StringF(SipStrConsts::ENotify) ||
+        	aType == SIPStrings::StringF(SipStrConsts::ESubscribe) ||        
+        	aType == SIPStrings::StringF(SipStrConsts::ERefer));
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::ResponseElements
+// -----------------------------------------------------------------------------
+//
+const CSIPResponseElements* CSIPTransactionBase::ResponseElements() const
+    {
+    return iResponseElements;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPTransactionBase::__DbgTestInvariant
+// -----------------------------------------------------------------------------
+//
+
+void CSIPTransactionBase::__DbgTestInvariant() const
+	{
+	if (!iRequestId)
+		{
+		User::Invariant();
+		}
+	}