realtimenetprots/sipfw/SIP/Registration/src/csipregisterupdating.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Registration/src/csipregisterupdating.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,231 @@
+// 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          : csipregisterupdating.cpp
+// Part of       : SIP Registration
+// Version       : SIP/4.0 
+//
+
+
+
+#include "csipregisterupdating.h"
+#include "csip423responsereceived.h"
+#include "sipcontactheader.h"
+#include "siprequest.h"
+#include "sipresponse.h"
+#include "CSIPRegistrar.h"
+#include "SipAssert.h"
+#include "sipminexpiresheader.h"
+#include "MRegistrationOwner.h"
+#include "CSIPResponseUtility.h"
+#include "siperr.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPRegisterUpdating* CSIPRegisterUpdating::NewL(
+	MRegistrationContext& aRegistration)
+	{
+	CSIPRegisterUpdating* self = CSIPRegisterUpdating::NewLC(aRegistration);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPRegisterUpdating* CSIPRegisterUpdating::NewLC(
+	MRegistrationContext& aRegistration)
+	{
+	CSIPRegisterUpdating* self =
+		new (ELeave) CSIPRegisterUpdating(aRegistration);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::SetNeighbourStates
+// -----------------------------------------------------------------------------
+//
+void CSIPRegisterUpdating::SetNeighbourStates(
+	CSIPRegistrationState* aResponse423Received,
+	CSIPRegistrationState* aRegistered,
+	CSIPRegistrationState* aUnregistered)
+	{
+	__SIP_ASSERT_RETURN(aResponse423Received, KErrArgument);
+    __SIP_ASSERT_RETURN(aRegistered, KErrArgument);
+	__SIP_ASSERT_RETURN(aUnregistered, KErrArgument);
+
+    iResponse423Received = aResponse423Received;
+	iRegistered = aRegistered;
+	iUnregistered = aUnregistered;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::~CSIPRegisterUpdating
+// -----------------------------------------------------------------------------
+//
+CSIPRegisterUpdating::~CSIPRegisterUpdating()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::UpdateL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegisterUpdating::UpdateL(TTransactionId& aTransactionId,
+				                   CSIPRequest*    aRequest)
+	{
+	__SIP_ASSERT_LEAVE(aRequest, KErrArgument);
+
+	CSIPContactHeader* contact = static_cast<CSIPContactHeader*>(
+		aRequest->Header(SIPStrings::StringF(SipStrConsts::EContactHeader),0));
+
+	__SIP_ASSERT_LEAVE(contact != 0, KErrArgument);
+		               
+	__SIP_ASSERT_LEAVE(contact->ExpiresParameter() > 0, KErrArgument);
+
+	// registrar must not be NULL after registering state.
+	__SIP_ASSERT_LEAVE(iRegistration.Registrar(), KErrGeneral);
+
+	// update registration expires parameter from aRequest Contact header
+	iRegistration.SetExpiresValueL(*aRequest);
+	// copy CallId and CSeq to request
+	iRegistration.Registrar()->FillCallIdAndCSeqL(*aRequest);
+	// copy To and From header to request
+	iRegistration.FillToFromL(*aRequest);
+
+	iRegistration.UpdateL(aTransactionId, aRequest);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::ReceiveL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegisterUpdating::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();
+		if (iRegistration.Request())
+			{
+			iRegistration.Request()->DeleteHeaders(
+				SIPStrings::StringF(SipStrConsts::ERouteHeader));
+			}
+        TInt err = 
+            CSIPResponseUtility::Check2XXResponse(iRegistration,*aResponse);
+        if (err)
+			{
+			iRegistration.ReceivedErrorResponseL();
+			User::LeaveIfError(
+			    PassErrorToOwner(err,aTransactionId,
+			                     iRegistration.RegistrationId()));
+			delete aResponse;
+			iRegistration.SelfDetach(ETrue);
+			iRegistration.ChangeState(iUnregistered); 
+			}
+		// if there is no error, call function Received2XXResponseL,
+		// which will update bindings, start timer for non refresh binding
+		else 
+			{
+			// function update the binding from response.
+			iRegistration.Received2XXResponseL(*aResponse,aTransactionId);
+			// pass response to owner
+			PassResponseToOwnerL(aResponse, aTransactionId, 
+				iRegistration.RegistrationId());
+			iRegistration.SelfDetach(EFalse);
+			// if the binding is non refresh binding, the request is deleted
+			// after 2xx received
+			iRegistration.ClearRequest();
+			iRegistration.ChangeState(iRegistered); 
+			}
+		}
+	else if (aResponse->IsErrorResponse())
+		{
+		// if 423 response is received and there is min expires header,
+		// set min expires header from response to request and send 
+		// the request again.
+        const RStringF KMinExpiresHeaderName = 
+            SIPStrings::StringF(SipStrConsts::EMinExpiresHeader);		
+		
+		if (aResponse->ResponseCode() == K423Response && 
+			aResponse->HasHeader(KMinExpiresHeaderName))
+			{
+			// function set min expires header from response to request.
+			iRegistration.Received423ResponseL(*aResponse);
+			iRegistration.ChangeState(iResponse423Received);
+			static_cast<CSIP423ResponseReceived*>(iResponse423Received)->
+				SetUpdate(ETrue);
+			iRegistration.CurrentState().RegisterL(
+			    aTransactionId,iRegistration.Request(),NULL);
+			delete aResponse;
+			}
+		// either response code is 423, but no MinExpires-header in response
+		// or response code not 423
+		else
+			{
+			// ReceivedErrorResponseL, remove binding 
+			iRegistration.ReceivedErrorResponseL();
+			// pass response to owner
+			PassResponseToOwnerL(aResponse, aTransactionId, 
+				iRegistration.RegistrationId());
+			iRegistration.SelfDetach(ETrue);
+			iRegistration.ChangeState(iUnregistered);
+			}
+		}
+	// response type == 1XX
+	else
+		{
+		// pass provisional response to owner
+		PassResponseToOwnerL(aResponse, aTransactionId, 
+			iRegistration.RegistrationId());
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::TransactionEnded
+// -----------------------------------------------------------------------------
+//
+TInt CSIPRegisterUpdating::TransactionEnded(TTransactionId aTransactionId, 
+		                                    TInt           aReason)
+	{
+	if (aReason != KErrNone)
+		{
+		iRegistration.ChangeState(iUnregistered);
+		}
+	// pass error to owner.
+	return (PassErrorToOwner(aReason, aTransactionId,
+		 iRegistration.RegistrationId()));	
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegisterUpdating::CSIPRegisterUpdating
+// -----------------------------------------------------------------------------
+//
+CSIPRegisterUpdating::CSIPRegisterUpdating(MRegistrationContext& aRegistration)
+	: CSIPRegistrationState (aRegistration)
+	{
+	}