--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Registration/src/CSIPResponseUtility.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,235 @@
+// 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 : CSIPResponseUtility.cpp
+// Part of : Registration
+// Version : SIP/6.0
+//
+
+
+
+
+#include "CSIPResponseUtility.h"
+#include "sipresponse.h"
+#include "uricontainer.h"
+#include "sipuri.h"
+#include "siphostport.h"
+#include "sipaddress.h"
+#include "siptoheader.h"
+#include "sipcontactheader.h"
+#include "sipcallidheader.h"
+#include "sipcseqheader.h"
+#include "sipexpiresheader.h"
+#include "sipviaheader.h"
+#include "mregistrationcontext.h"
+#include "SipAssert.h"
+#include "siperr.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::IsError
+// -----------------------------------------------------------------------------
+//
+TBool CSIPResponseUtility::IsError(CSIPResponse& aSIPResponse)
+ {
+ return (aSIPResponse.IsErrorResponse());
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::ContactHeader
+// -----------------------------------------------------------------------------
+//
+CSIPContactHeader* CSIPResponseUtility::ContactHeader(
+ CSIPContactHeader& aContactInBinding,
+ CSIPResponse& aResponse)
+ {
+ TSglQueIter<CSIPHeaderBase> contact =
+ aResponse.Headers(SIPStrings::StringF(SipStrConsts::EContactHeader));
+
+ if (aResponse.HeaderCount(
+ SIPStrings::StringF(SipStrConsts::EContactHeader)) == 1)
+ {
+ return static_cast<CSIPContactHeader*>(contact++);
+ }
+
+ for (CSIPHeaderBase* header = contact++; header; header = contact++)
+ {
+ CSIPContactHeader* contactHeader =
+ static_cast<CSIPContactHeader*>(header);
+
+ if (contactHeader->SIPAddress() &&
+ contactHeader->SIPAddress()->URI().IsSIPURI() &&
+ aContactInBinding.SIPAddress()->URI().IsSIPURI())
+ {
+ if (contactHeader->SIPAddress()->URI().SIPURI()->User() ==
+ aContactInBinding.SIPAddress()->URI().SIPURI()->User())
+ {
+ return contactHeader;
+ }
+ }
+ else
+ {
+ if (contactHeader->SIPAddress() &&
+ contactHeader->SIPAddress()->URI() ==
+ aContactInBinding.SIPAddress()->URI())
+ {
+ return contactHeader;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::CallIdL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSIPResponseUtility::CallIdL(CSIPResponse& aSIPResponse)
+ {
+ CSIPCallIDHeader* callId = aSIPResponse.CallID();
+
+ // panic if there is no CallId header in response
+ __SIP_ASSERT_LEAVE (callId, KErrArgument);
+
+ return (callId->ToTextValueL());
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::CSeqValueL
+// -----------------------------------------------------------------------------
+//
+TUint CSIPResponseUtility::CSeqValueL(CSIPResponse& aSIPResponse)
+ {
+ CSIPCSeqHeader* cseq = aSIPResponse.CSeq();
+
+ // panic if there is no CSeq header in response
+ __SIP_ASSERT_LEAVE (cseq, KErrArgument);
+
+ return cseq->Seq();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::ExpireValueL
+// -----------------------------------------------------------------------------
+//
+TUint CSIPResponseUtility::ExpireValueL(CSIPContactHeader& aBindingContact,
+ CSIPResponse& aResponse)
+ {
+ const RStringF KExpiresHeaderName =
+ SIPStrings::StringF(SipStrConsts::EExpiresHeader);
+ TUint returnValue = 0;
+
+ // get Contact header from response
+ CSIPContactHeader* responseContact =
+ ContactHeader(aBindingContact, aResponse);
+
+ if (responseContact)
+ {
+ if (responseContact->ExpiresParameter() < 0)
+ {
+ if (aResponse.HasHeader(KExpiresHeaderName))
+ {
+ // copy the expires value from expires header to
+ // expires parameter in contact, remove the expires header
+ CSIPExpiresHeader* expiresHeader =
+ static_cast<CSIPExpiresHeader*>(
+ aResponse.Header(KExpiresHeaderName,0));
+
+ responseContact->SetExpiresParameterL(
+ expiresHeader->Value());
+
+ if (aResponse.RemoveHeader(expiresHeader) == KErrNone)
+ {
+ delete expiresHeader; expiresHeader = 0;
+ }
+ }
+ else
+ {
+ // copy the expires parameter from binding
+ responseContact->SetExpiresParameterL(
+ aBindingContact.ExpiresParameter());
+ }
+ }
+ // if expires parameter is not zero and expires parameter in binding
+ // less than expires parameter in response, change expires parameter
+ // in response to lower value
+ if (aBindingContact.ExpiresParameter() != 0 &&
+ (aBindingContact.ExpiresParameter() <
+ responseContact->ExpiresParameter()))
+ {
+ responseContact->SetExpiresParameterL(
+ aBindingContact.ExpiresParameter());
+ }
+
+ returnValue = responseContact->ExpiresParameter();
+ }
+
+ return returnValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPResponseUtility::Check2XXResponse
+// -----------------------------------------------------------------------------
+//
+TInt CSIPResponseUtility::Check2XXResponse(MRegistrationContext& aRegistration,
+ CSIPResponse& aResponse)
+ {
+ TInt err = KErrNone;
+ const RStringF KContactHeaderName =
+ SIPStrings::StringF(SipStrConsts::EContactHeader);
+ // error if there is no contact header in response
+ if (!aResponse.HasHeader(KContactHeaderName))
+ {
+ return KErrSIPInvalidRegistrarResponse;
+ }
+ // error if contact header sip address in response is different as contact
+ // header sip address in response
+ if (!ContactHeader(aRegistration.Contact(),aResponse))
+ {
+ return KErrSIPInvalidRegistrarResponse;
+ }
+ // if there is no expires parameter or expires header in response,
+ // copy te expires parameter from binding.
+ // error if the expires parameter is 0 in response.
+ TUint expireValue = 0;
+ TRAP(err, expireValue = ExpireValueL(aRegistration.Contact(),aResponse))
+ if (err)
+ {
+ return err;
+ }
+ if (expireValue == 0)
+ {
+ return KErrSIPInvalidRegistrarResponse;
+ }
+ // Invalid Service-Route must be indicated to SIP Profile Agent
+ // as a transport failure. This will lead to a new registration.
+ if (!aRegistration.ServiceRouteOk(aResponse))
+ {
+ return KErrSIPTransportFailure;
+ }
+
+ const CURIContainer& uriOfToInBinding =
+ aRegistration.AOR().SIPAddress().URI();
+
+ CURIContainer& uriOfToInResponse =
+ aResponse.To()->SIPAddress().URI();
+
+ if (!(uriOfToInBinding == uriOfToInResponse))
+ {
+ err = KErrSIPInvalidRegistrarResponse;
+ }
+ return err;
+ }