realtimenetprots/sipfw/ProfileAgent/IMS_Agent/Src/CSIPRegEventSubscriber.cpp
changeset 0 307788aac0a8
child 51 8134400f8f89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ProfileAgent/IMS_Agent/Src/CSIPRegEventSubscriber.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,732 @@
+// 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        : CSIPRegEventSubscriber.cpp
+// Part of     : SIP Profile Agent
+// implementation
+// Version     : 1.0
+//
+
+
+
+
+// INCLUDE FILES
+#include "CSIPRegEventSubscriber.h"
+#include "CSIPNotifyXmlBodyParser.h"
+#include "sipreginfoelement.h"
+#include "TSIPRegEventStateNotSubscribed.h"
+#include "TSIPRegEventStateSubscribing.h"
+#include "TSIPRegEventStateSubscribed.h"
+#include "TSIPRegEventStateReSubscribing.h"
+#include "sipfromheader.h"
+#include "siptoheader.h"
+#include "sipeventheader.h"
+#include "siprefresh.h"
+#include "sipmessageelements.h"
+#include "sipexpiresheader.h"
+#include "sipacceptheader.h"
+#include "sipcontenttypeheader.h"
+#include "sipsubscriptionstateheader.h"
+#include "sipretryafterheader.h"
+#include "sipresponseelements.h"
+#include "siperr.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include <sipprofileagentextensionparams.h>
+
+
+_LIT8(KRegEventName, "reg");
+_LIT8(KAcceptType, "application");
+_LIT8(KAcceptSubtype, "reginfo+xml");
+_LIT8(KStateActive, "active");
+_LIT8(KStatePending, "pending");
+_LIT8(KStateTerminated, "terminated");
+_LIT8(KReasonProbation, "probation");
+_LIT8(KReasonRejected, "rejected");
+_LIT8(KReasonGiveup, "giveup");
+_LIT8(KReasonNoresource, "noresource");
+
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventSubscriber* CSIPRegEventSubscriber::NewL(
+    CSIPNotifyXmlBodyParser& aXmlParser,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    CUri8& aUserIdentity,
+    MSIPRegEventSubscriberObserver& aObserver,
+    CSipProfileAgentConfigExtension& aConfigExtension)
+	{
+	CSIPRegEventSubscriber* self = 
+	    NewLC(aXmlParser,aConnection,aContext,aUserIdentity,aObserver,aConfigExtension);
+	CleanupStack::Pop();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventSubscriber* CSIPRegEventSubscriber::NewLC(
+    CSIPNotifyXmlBodyParser& aXmlParser,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    CUri8& aUserIdentity,
+    MSIPRegEventSubscriberObserver& aObserver,
+    CSipProfileAgentConfigExtension& aConfigExtension)
+	{
+	CSIPRegEventSubscriber* self = 
+	    new(ELeave)CSIPRegEventSubscriber(
+	        aXmlParser,aConnection,aContext,aUserIdentity,aObserver,aConfigExtension);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::CSIPRegEventSubscriber
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventSubscriber::CSIPRegEventSubscriber(
+    CSIPNotifyXmlBodyParser& aXmlParser,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    CUri8& aUserIdentity,
+    MSIPRegEventSubscriberObserver& aObserver,
+    CSipProfileAgentConfigExtension& aConfigExtension)
+ : iStates(MSIPRegEventContext::EMaxStates),
+   iCurrentState(MSIPRegEventContext::ENotSubscribed),
+   iXmlParser(aXmlParser),
+   iConnection(aConnection),
+   iRegistrationContext(aContext),
+   iUserIdentity(aUserIdentity),
+   iObserver(aObserver),
+   iConfigExtension(aConfigExtension)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventSubscriber::ConstructL()
+	{
+	InitializeStatesL();
+    iReasonProbation = SIPStrings::Pool().OpenFStringL(KReasonProbation);
+    iReasonRejected = SIPStrings::Pool().OpenFStringL(KReasonRejected);
+    iReasonGiveup = SIPStrings::Pool().OpenFStringL(KReasonGiveup);
+    iReasonNoresource = SIPStrings::Pool().OpenFStringL(KReasonNoresource);
+    iSubscribeAssoc = CreateSubscribeAssocL();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::InitializeStatesL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::InitializeStatesL()
+    {
+	iStates.AppendL(TSIPRegEventStateNotSubscribed(*this),
+					sizeof(TSIPRegEventStateNotSubscribed));
+					
+	iStates.AppendL(TSIPRegEventStateSubscribing(*this),
+					sizeof(TSIPRegEventStateSubscribing));					
+					
+	iStates.AppendL(TSIPRegEventStateSubscribed(*this),
+					sizeof(TSIPRegEventStateSubscribed));
+					
+	iStates.AppendL(TSIPRegEventStateReSubscribing(*this),
+					sizeof(TSIPRegEventStateReSubscribing));
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::~CSIPRegEventSubscriber
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventSubscriber::~CSIPRegEventSubscriber()
+	{
+	delete iSubscribeAssoc;
+	delete iClientTransaction;
+    iReasonProbation.Close();
+    iReasonRejected.Close();
+    iReasonGiveup.Close();
+    iReasonNoresource.Close();
+    delete iCurrentRegInfoElement;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::SubscribeL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::SubscribeL()
+    {
+    CurrentState().SubscribeL();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::DoSubscribeL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::DoSubscribeL()
+    {
+    CSIPRefresh* refresh = CSIPRefresh::NewLC();
+    CSIPMessageElements* message = CreateMessageElementsLC(
+            iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms,
+            CSipProfileAgentConfigExtension::EProfileSubscriptionValue));
+    
+    CSIPClientTransaction* transaction = 
+        iSubscribeAssoc->SendSubscribeL(message,refresh);
+    
+    CleanupStack::Pop(message);
+    CleanupStack::Pop(refresh);
+    delete iClientTransaction;
+    iClientTransaction = transaction;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ReSubscribeL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::ReSubscribeL()
+    {
+    CSIPSubscribeDialogAssoc* subscribeAssoc = CreateSubscribeAssocL();
+    CleanupStack::PushL(subscribeAssoc);
+    
+    CSIPRefresh* refresh = CSIPRefresh::NewLC();
+    CSIPMessageElements* message = CreateMessageElementsLC(
+            iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms,
+            CSipProfileAgentConfigExtension::EProfileSubscriptionValue));
+    
+    CSIPClientTransaction* transaction = 
+        subscribeAssoc->SendSubscribeL(message,refresh);    
+
+    CleanupStack::Pop(message);
+    CleanupStack::Pop(refresh);
+    delete iClientTransaction;
+    iClientTransaction = transaction;
+    
+    CleanupStack::Pop(subscribeAssoc);
+    delete iSubscribeAssoc;
+    iSubscribeAssoc = subscribeAssoc;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::RefreshL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::RefreshL()
+    {
+    CurrentState().RefreshL();
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::DoRefreshL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::DoRefreshL()
+    {
+    CSIPMessageElements* message = CreateMessageElementsLC(
+            iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms,
+            CSipProfileAgentConfigExtension::EProfileSubscriptionValue));
+    
+    CSIPClientTransaction* transaction = iSubscribeAssoc->UpdateL(message);
+    
+    CleanupStack::Pop(message);
+    delete iClientTransaction;
+    iClientTransaction = transaction;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ReSubscribeAfterL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::ReSubscribeAfterL(TUint aRetryAfter)
+    {
+    iObserver.SubscriptionFailedL(aRetryAfter);
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::SubscriptionFailedL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::SubscriptionFailedL()
+    {
+    iObserver.SubscriptionFailedL();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::RegEventNotSupportedByNetworkL
+// -----------------------------------------------------------------------------
+// 
+void CSIPRegEventSubscriber::RegEventNotSupportedByNetworkL()
+    {
+    iObserver.RegEventNotSupportedByNetworkL();
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ReRegister
+// -----------------------------------------------------------------------------
+//   
+void CSIPRegEventSubscriber::ReRegister()
+    {
+    iObserver.ReRegister();
+    }
+      
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ChangeState
+// -----------------------------------------------------------------------------
+//      
+void CSIPRegEventSubscriber::ChangeState(TState aNewState)
+    {
+    iCurrentState = aNewState;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HasTransaction
+// -----------------------------------------------------------------------------
+// 	    
+TBool CSIPRegEventSubscriber::HasTransaction(
+    const CSIPTransactionBase& aTransaction) const
+    {
+    return (iClientTransaction && aTransaction == *iClientTransaction);
+    }    
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HasRefresh
+// -----------------------------------------------------------------------------
+// 	    
+TBool CSIPRegEventSubscriber::HasRefresh(
+    const CSIPRefresh& aRefresh) const
+    {
+    return (*iSubscribeAssoc->SIPRefresh() == aRefresh);
+    } 
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HasDialog
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventSubscriber::HasDialog(const CSIPDialog& aDialog) const
+    {
+    return (aDialog == iSubscribeAssoc->Dialog());
+    }
+    	
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::RequestReceivedL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventSubscriber::RequestReceivedL(
+    CSIPServerTransaction* aTransaction,
+    CSIPDialog& aDialog)
+    {
+    if (HasDialog(aDialog))
+        {
+        __ASSERT_ALWAYS(aTransaction, User::Leave(KErrCorrupt));
+        __ASSERT_ALWAYS(aTransaction->RequestElements() != NULL, 
+                        User::Leave(KErrCorrupt));
+        const CSIPRequestElements& request = *(aTransaction->RequestElements());  
+        CSIPResponseElements* response = HandleReceivedRequestLC(request);
+        if (response->StatusCode() == 200)
+            {
+            TRAPD(err, ParseXmlL(request));
+            if (err == KErrNone)
+                {
+                TBool terminated = EFalse;
+                TInt retryAfter = 0;
+                HandleSubscriptionStateL(request,terminated,retryAfter); 
+                aTransaction->SendResponseL(response);
+                CleanupStack::Pop(response);
+                if (terminated)
+                    {
+                    iObserver.TerminatedL(*iCurrentRegInfoElement,retryAfter);
+                    }
+                else
+                    {
+                    iObserver.NotifyReceivedL(*iCurrentRegInfoElement);
+                    } 
+                }
+            else if (err == KErrNoMemory)
+                {
+                User::Leave(err);
+                }
+            else
+                {
+                response->SetStatusCodeL(400);
+                response->SetReasonPhraseL(
+                    SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
+                aTransaction->SendResponseL(response);
+                CleanupStack::Pop(response);               
+                } 
+            }
+        else
+            {
+            aTransaction->SendResponseL(response);
+            CleanupStack::Pop(response);
+            }
+        delete aTransaction;
+        }
+    }
+	
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ResponseReceivedL
+// -----------------------------------------------------------------------------
+//					           
+void CSIPRegEventSubscriber::ResponseReceivedL(
+    CSIPClientTransaction& aTransaction)
+    {
+    if (HasTransaction(aTransaction))
+        {
+        const CSIPResponseElements* response = aTransaction.ResponseElements();
+        __ASSERT_ALWAYS(response != NULL, User::Leave(KErrCorrupt));        
+        HandleReceivedResponseL(*response);
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ErrorOccured
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventSubscriber::ErrorOccured(
+    TInt /*aError*/,
+    CSIPTransactionBase& aTransaction)
+    {
+    if (HasTransaction(aTransaction))
+        {
+        TRAP_IGNORE(CurrentState().ErrorOccuredL())
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ErrorOccured
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::ErrorOccured(TInt aError,
+                                          CSIPDialog& aDialog)
+    {
+    if (HasDialog(aDialog))
+        {
+        const CSIPClientTransaction* transaction = 
+            iSubscribeAssoc->SIPRefresh()->SIPTransaction();
+        if (transaction && aError == KErrSIPTerminatedWithResponse)
+            {
+            TUint statusCode = transaction->ResponseElements()->StatusCode();
+            TUint after = RetryAfterValue(*transaction->ResponseElements());
+            TRAP_IGNORE(CurrentState().ResponseReceivedL(statusCode,after))
+            }
+        else
+            {
+            TRAP_IGNORE(CurrentState().ErrorOccuredL())
+            }
+        }
+    }    
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HandleReceivedRequestLC
+// -----------------------------------------------------------------------------
+//
+CSIPResponseElements* CSIPRegEventSubscriber::HandleReceivedRequestLC(
+    const CSIPRequestElements& aRequest)
+    {
+    if (!MethodOK(aRequest) || 
+        !ContentTypeOK(aRequest) ||
+        !SubscriptionStateOK(aRequest))
+        {
+        return CSIPResponseElements::NewLC(400,
+            SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
+        }
+        
+    if (!EventOK(aRequest))
+        {
+        return CSIPResponseElements::NewLC(489,
+            SIPStrings::StringF(SipStrConsts::EPhraseBadEvent));
+        }
+
+    return CSIPResponseElements::NewLC(200,
+        SIPStrings::StringF(SipStrConsts::EPhraseOk));    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HandleReceivedResponseL
+// -----------------------------------------------------------------------------
+//					           
+void CSIPRegEventSubscriber::HandleReceivedResponseL(
+    const CSIPResponseElements& aResponse)
+    {
+    TUint statusCode = aResponse.StatusCode();
+    if (statusCode >= 200)
+        {
+        TUint retryAfter = RetryAfterValue(aResponse);
+        delete iClientTransaction;
+        iClientTransaction = NULL;
+        CurrentState().ResponseReceivedL(statusCode,retryAfter);
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::RetryAfterValue
+// -----------------------------------------------------------------------------
+//    
+TUint CSIPRegEventSubscriber::RetryAfterValue(
+    const CSIPResponseElements& aResponse) const
+    {
+    TUint retryAfter = 0;
+    CSIPRetryAfterHeader* retryAfterHeader = 
+        static_cast<CSIPRetryAfterHeader*>(
+            FindHeader(aResponse.MessageElements(),
+                SIPStrings::StringF(SipStrConsts::ERetryAfterHeader)));
+    if (retryAfterHeader)
+        {
+        retryAfter = retryAfterHeader->RetryAfter();
+        }
+    return retryAfter;
+    }    
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ParseXmlL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::ParseXmlL(const CSIPRequestElements& aRequest)
+    {
+    CSIPRegInfoElement* regInfoElement = CSIPRegInfoElement::NewLC();
+    iXmlParser.ParseL(regInfoElement,aRequest.MessageElements().Content());
+    CleanupStack::Pop(regInfoElement);
+    delete iCurrentRegInfoElement;
+    iCurrentRegInfoElement = regInfoElement;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HandleSubscriptionStateL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::HandleSubscriptionStateL(
+    const CSIPRequestElements& aRequest,
+    TBool& aTerminated,
+    TInt& aRetryAfter)
+    {
+    TBool terminated = EFalse;
+    
+    CSIPHeaderBase* header = 
+        FindHeader(aRequest.MessageElements(),
+            SIPStrings::StringF(SipStrConsts::ESubscriptionStateHeader));
+            
+    __ASSERT_ALWAYS(header != NULL, User::Leave(KErrCorrupt));        
+            
+    CSIPSubscriptionStateHeader* ssHeader = 
+        static_cast<CSIPSubscriptionStateHeader*>(header);
+
+    CSIPRefresh* refresh = 
+        const_cast<CSIPRefresh*>(iSubscribeAssoc->SIPRefresh());
+        
+    TPtrC8 state(ssHeader->SubStateValue());
+    
+    if (state.CompareF(KStateActive) == 0 || 
+        state.CompareF(KStatePending) == 0)
+        {
+        TInt expires = ssHeader->ExpiresParameter();
+        if (expires > 0)
+            {
+            refresh->SetIntervalL(static_cast<TUint>(expires));   
+            }
+        }
+    else if (state.CompareF(KStateTerminated) == 0)
+        {
+        HandleTerminatedState(*ssHeader, aRetryAfter);
+        terminated = ETrue;
+        }
+    else // Unknown state
+        {
+        // Just refresh after one minute
+        refresh->SetIntervalL(60);
+        }
+        
+    aTerminated = terminated;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::HandleTerminatedState
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventSubscriber::HandleTerminatedState(
+    CSIPSubscriptionStateHeader& aState,
+    TInt& aRetryAfter)
+    {
+    TInt retryAfter = aState.RetryAfterParameter();
+    
+    RStringF reason = 
+        aState.ParamValue(SIPStrings::StringF(SipStrConsts::EReason));
+        
+    if (reason == iReasonProbation ||
+        reason == iReasonGiveup)
+        {
+        if (retryAfter < 0)
+            {
+            // re-SUBSCRIBE after one hour
+            retryAfter = 3600;
+            }
+        }
+    else if (reason == iReasonRejected ||
+             reason == iReasonNoresource)
+        {
+        // do NOT re-SUBSRIBE
+        retryAfter = -1;
+        }
+    else
+        {
+        //  deactivated, timeout or anything else: re-SUBSCRIBE immediately
+        retryAfter = 0;
+        }
+        
+    aRetryAfter = retryAfter;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::CreateSubscribeAssocL
+// -----------------------------------------------------------------------------
+//   
+CSIPSubscribeDialogAssoc* CSIPRegEventSubscriber::CreateSubscribeAssocL()
+    {
+	TPtrC8 uriDes(iUserIdentity.Uri().UriDes());
+	CUri8* remoteUri = CUri8::NewLC(iUserIdentity.Uri());
+	CSIPFromHeader* from = CSIPFromHeader::DecodeL(uriDes);
+	CleanupStack::PushL(from);
+	CSIPEventHeader* event = CSIPEventHeader::NewLC(KRegEventName);
+    
+    CSIPSubscribeDialogAssoc* subscribeAssoc = 
+        CSIPSubscribeDialogAssoc::NewL(iConnection,remoteUri,
+                                       iRegistrationContext,event,from);
+        
+    CleanupStack::Pop(event);
+    CleanupStack::Pop(from);
+    CleanupStack::Pop(remoteUri);
+    
+    return subscribeAssoc;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::CreateMessageElementsLC
+// -----------------------------------------------------------------------------
+//    
+CSIPMessageElements* 
+CSIPRegEventSubscriber::CreateMessageElementsLC(TUint aExpiresValue)
+    {
+    CSIPMessageElements* message = CSIPMessageElements::NewLC();
+    RPointerArray<CSIPHeaderBase> headers;
+    CSIPHeaderBase::PushLC(&headers);
+    // Expires
+    CSIPExpiresHeader* expires = new(ELeave)CSIPExpiresHeader(aExpiresValue);
+    CleanupStack::PushL(expires);
+    headers.AppendL(expires);
+    CleanupStack::Pop(expires);
+    // Accept
+    CSIPAcceptHeader* accept = 
+        CSIPAcceptHeader::NewLC(KAcceptType,KAcceptSubtype);
+    headers.AppendL(accept);
+    CleanupStack::Pop(accept); 
+    message->SetUserHeadersL(headers);
+    CleanupStack::Pop(1); // headers
+    headers.Close();
+    return message;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::MethodOK
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventSubscriber::MethodOK(const CSIPRequestElements& aRequest)
+    {
+    return (aRequest.Method() == SIPStrings::StringF(SipStrConsts::ENotify));  
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::ContentTypeOK
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventSubscriber::ContentTypeOK(const CSIPRequestElements& aRequest)
+    {
+    const CSIPContentTypeHeader* contentType = 
+        aRequest.MessageElements().ContentType();
+    if (!contentType)
+        {
+        return EFalse;
+        }
+    if (contentType->MediaType().CompareF(KAcceptType) != 0)
+        {
+        return EFalse;
+        }
+    return (contentType->MediaSubtype().CompareF(KAcceptSubtype) == 0);
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::SubscriptionStateOK
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventSubscriber::SubscriptionStateOK(
+    const CSIPRequestElements& aRequest)
+    {
+    CSIPHeaderBase* header = 
+        FindHeader(aRequest.MessageElements(),
+            SIPStrings::StringF(SipStrConsts::ESubscriptionStateHeader));
+    return (header != NULL);
+    }    
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::EventOK
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventSubscriber::EventOK(const CSIPRequestElements& aRequest)
+    {
+    CSIPHeaderBase* header = 
+        FindHeader(aRequest.MessageElements(),
+            SIPStrings::StringF(SipStrConsts::EEventHeader));
+    if (!header)
+        {
+        return EFalse;
+        }
+    CSIPEventHeader* event = static_cast<CSIPEventHeader*>(header);
+    return (event->EventPackage().CompareF(KRegEventName) == 0);
+    }    
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::FindHeader
+// -----------------------------------------------------------------------------
+// 
+CSIPHeaderBase* CSIPRegEventSubscriber::FindHeader(
+    const CSIPMessageElements& aMessage,
+    RStringF aHeaderName) const
+    {
+    TBool found = EFalse;
+    CSIPHeaderBase* header = NULL;
+    const RPointerArray<CSIPHeaderBase>& headers = aMessage.UserHeaders();
+    for (TInt i=0; i < headers.Count() && !found; i++)
+        {
+        header = headers[i];
+        if (header->Name() == aHeaderName)
+            {
+            found = ETrue;
+            }
+        else
+            {
+            header = NULL;
+            }
+        }
+    return header;
+    }
+    
+// ----------------------------------------------------------------------------
+// CSIPRegEventSubscriber::CurrentState
+// ----------------------------------------------------------------------------
+//
+TSIPRegEventSubscriptionStateBase& CSIPRegEventSubscriber::CurrentState()
+	{
+	return iStates.At(iCurrentState);
+	}