realtimenetprots/sipfw/SIP/Registration/src/csip423responsereceived.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Registration/src/csip423responsereceived.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,266 @@
+// 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          : csip423responsereceived.cpp
+// Part of       : SIP Registration
+// Version       : SIP/4.0 
+//
+
+
+
+#include "csip423responsereceived.h"
+#include "siprequest.h"
+#include "sipresponse.h"
+#include "sipcseqheader.h"
+#include "SipAssert.h"
+#include "MRegistrationOwner.h"
+#include "sipcontactheader.h"
+#include "CSIPRegistrar.h"
+#include "CSIPResponseUtility.h"
+#include "siperr.h"
+
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::NewL
+// -----------------------------------------------------------------------------
+//
+CSIP423ResponseReceived* CSIP423ResponseReceived::NewL(
+	MRegistrationContext& aRegistration)
+	{
+	CSIP423ResponseReceived* self = 
+		CSIP423ResponseReceived::NewLC(aRegistration);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIP423ResponseReceived* CSIP423ResponseReceived::NewLC(
+	MRegistrationContext& aRegistration)
+	{
+	CSIP423ResponseReceived* self = 
+		new (ELeave) CSIP423ResponseReceived(aRegistration);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::SetNeighbourStates
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::SetNeighbourStates(
+	CSIPRegistrationState* aRegistered,
+    CSIPRegistrationState* aUnregistered)
+	{
+	__SIP_ASSERT_RETURN(aRegistered, KErrArgument);
+    __SIP_ASSERT_RETURN(aUnregistered, KErrArgument);
+
+	iRegistered = aRegistered;
+    iUnregistered = aUnregistered;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::~CSIP423ResponseReceived
+// -----------------------------------------------------------------------------
+//
+CSIP423ResponseReceived::~CSIP423ResponseReceived()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::RegisterL
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::RegisterL(TTransactionId&  aTransactionId, 
+	  	                                CSIPRequest*     aRequest,
+		                                CSIPRouteHeader* aOutboundProxy)
+	{
+	__SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+
+	CSIPCSeqHeader* cseq = aRequest->CSeq();
+	if (iRegistration.Registrar())
+		{	
+		// if there is Registrar, the CallId and CSeq must be filled-in
+		// from CSIPRegistering state. the CSeq need to be increased for 
+		// sending REGISTER request again in this state. so panic if there is 
+		// no CSeq header in debug mode,leave in release mode
+		__SIP_ASSERT_LEAVE(cseq != 0, KErrGeneral);
+		// increase the cseq for registrar
+		iRegistration.Registrar()->IncreaseCSeqNumber();
+		cseq->SetSeq(iRegistration.Registrar()->CSeqNumber());
+		}
+	else
+		{	
+		// to check if the CSeq has been filled by lower layer,
+		// if so, increase the CSeq by one before sending the request.
+		if (cseq)
+			{
+			cseq->SetSeq(cseq->Seq()+1);
+			}
+		}
+
+	iRegistration.RegisterL(aTransactionId, aRequest, aOutboundProxy);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::ReceiveL
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::ReceiveL(TTransactionId aTransactionId,
+		                               CSIPResponse*  aResponse)
+	{
+	__SIP_ASSERT_LEAVE(aResponse, KErrArgument);
+	// the expires parameter value must not be 0, other wise panic in debug
+	// mode, leaves in release mode.
+	__SIP_ASSERT_LEAVE(iRegistration.Contact().ExpiresParameter() > 0, 
+		KErrGeneral);
+
+	if (aResponse->Type() == CSIPResponse::E2XX)
+		{
+		// ConnectionMgr may have changed the the host part of the Contact
+		iRegistration.UpdateContactFromRequestL();
+        TInt err = 
+            CSIPResponseUtility::Check2XXResponse(iRegistration,*aResponse);		
+		if (err)
+			{
+			iRegistration.ReceivedErrorResponseL();
+			PassErrorL(err,aTransactionId);
+			delete aResponse;
+			iRegistration.SelfDetach(ETrue);
+			iRegistration.ChangeState(iUnregistered); 
+			}
+		else
+			{
+			iRegistration.Received2XXResponseL(*aResponse,aTransactionId);
+			// pass response to owner, registration id should be passed
+			// since 2xx ok response received.
+			PassResponseToOwnerL(aResponse, aTransactionId, 
+				iRegistration.RegistrationId());
+				
+			// if EFalse,detach from lowerlayer only for nonrefresh binding.
+			// Use overloaded version of SelfDetatch function
+			// to detatch retry transaction.
+			iRegistration.SelfDetach(EFalse, ETrue);
+			
+			// if the binding is non refresh binding, the request is deleted.
+			iRegistration.ClearRequest();
+			iRegistration.ChangeState(iRegistered); 
+			}
+		}
+	else if (aResponse->IsErrorResponse())
+		{
+		// ReceivedErrorResponseL, remove binding 
+		iRegistration.ReceivedErrorResponseL();
+		// pass response to owner
+		PassResponseL(aResponse, aTransactionId);
+		iRegistration.SelfDetach(ETrue);
+		iRegistration.ChangeState(iUnregistered);
+		}
+	else // response type == 1XX
+		{
+		// pass provisional response to owner
+		PassResponseL(aResponse, aTransactionId);
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::TransactionEnded
+// -----------------------------------------------------------------------------
+//
+TInt CSIP423ResponseReceived::TransactionEnded(TTransactionId aTransactionId, 
+		                                       TInt           aReason)
+	{
+	if (aReason != KErrNone)
+		{
+		iRegistration.ChangeState(iUnregistered);
+		}
+	// pass error to owner. 
+	if (iUpdate)
+		{
+		return (PassErrorToOwner(aReason, aTransactionId,
+			iRegistration.RegistrationId()));	
+		}
+	else
+		{
+		return (PassErrorToOwner(aReason, aTransactionId));
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::Retrying
+// -----------------------------------------------------------------------------
+//
+
+TBool CSIP423ResponseReceived::Retrying() const
+
+	{
+	return ETrue;	
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::SetUpdate
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::SetUpdate(TBool aUpdate)
+	{
+	iUpdate = aUpdate;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::CSIP423ResponseReceived
+// -----------------------------------------------------------------------------
+//
+CSIP423ResponseReceived::CSIP423ResponseReceived(
+	MRegistrationContext& aRegistration) 
+	: CSIPRegistrationState (aRegistration),
+	iUpdate                 (EFalse)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::PassResponseL
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::PassResponseL(CSIPResponse*   aResponse,
+											TTransactionId  aTransactionId)
+	{
+	if (iUpdate)
+		{
+		PassResponseToOwnerL(aResponse, aTransactionId, 
+			iRegistration.RegistrationId());
+		}
+	else
+		{
+		PassResponseToOwnerL(aResponse, aTransactionId);
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIP423ResponseReceived::PassErrorL
+// -----------------------------------------------------------------------------
+//
+void CSIP423ResponseReceived::PassErrorL(TInt aError, 
+										 TTransactionId  aTransactionId)
+	{
+	if (iUpdate)
+		{
+		User::LeaveIfError(PassErrorToOwner(aError, aTransactionId,
+			iRegistration.RegistrationId()));	
+		}
+	else
+		{
+		User::LeaveIfError(PassErrorToOwner(aError, aTransactionId));
+		}
+	}