realtimenetprots/sipfw/ProfileAgent/IMS_Agent/Src/CSIPRegEventHandler.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ProfileAgent/IMS_Agent/Src/CSIPRegEventHandler.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,586 @@
+// 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        : CSIPRegEventHandler.cpp
+// Part of     : SIP Profile Agent
+// implementation
+// Version     : 1.0
+//
+
+
+
+
+// INCLUDE FILES
+#include "CSIPRegEventHandler.h"
+#include "CSIPRegEventSubscriber.h"
+#include "CSIPNotifyXmlBodyParser.h"
+#include "sipcontactelement.h"
+#include "sipregistrationelement.h"
+
+const TInt KMicroSecsInSec = 1000000;
+
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventHandler* CSIPRegEventHandler::NewL(
+    CSIPNotifyXmlBodyParser& aXMLParser,
+    const TDesC8& aLocalIP,
+    CDeltaTimer& aDeltaTimer,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    CUri8& aUserIdentity,
+    MSIPRegEventObserver& aObserver,
+    CSipProfileAgentConfigExtension& aConfigExtension)
+	{
+	CSIPRegEventHandler* self = 
+	    CSIPRegEventHandler::NewLC(aXMLParser,aLocalIP,aDeltaTimer,
+	        aConnection,aContext,aUserIdentity,aObserver,aConfigExtension);
+	CleanupStack::Pop();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventHandler* CSIPRegEventHandler::NewLC(
+    CSIPNotifyXmlBodyParser& aXMLParser,
+    const TDesC8& aLocalIP,
+    CDeltaTimer& aDeltaTimer,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    CUri8& aUserIdentity,
+    MSIPRegEventObserver& aObserver,
+    CSipProfileAgentConfigExtension& aConfigExtension)
+	{
+	CSIPRegEventHandler* self = 
+	    new(ELeave)CSIPRegEventHandler(aXMLParser,aDeltaTimer,aConnection,
+	        aContext,aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL(aLocalIP,aUserIdentity,aConfigExtension);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::CSIPRegEventHandler
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventHandler::CSIPRegEventHandler(
+    CSIPNotifyXmlBodyParser& aXMLParser,
+    CDeltaTimer& aDeltaTimer,
+    CSIPConnection& aConnection,
+    MSIPRegistrationContext& aContext,
+    MSIPRegEventObserver& aObserver)
+ : iXMLParser(aXMLParser),
+   iDeltaTimer(aDeltaTimer),
+   iConnection(aConnection),
+   iRegistrationContext(aContext),
+   iObserver(aObserver),
+   iDeltaTimerCallBack(ReSubscribeTimerExpired,this),
+   iFirstNotifyProcessed(EFalse)
+	{
+	iDeltaTimerEntry.Set(iDeltaTimerCallBack);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::ConstructL(const TDesC8& aLocalIP,
+                                     CUri8& aUserIdentity,
+                                     CSipProfileAgentConfigExtension& aConfigExtension)
+	{
+    iLocalIP = aLocalIP.AllocL();
+	iUserId = CUri8::NewL(aUserIdentity.Uri());
+    // String constants for XML
+    RStringPool& stringPool = iXMLParser.StringPool();
+    iStrFull = stringPool.OpenStringL(_L8("full"));
+	iStrActive = stringPool.OpenStringL(_L8("active"));
+    iStrTerminated = stringPool.OpenStringL(_L8("terminated"));
+    iStrShortened = stringPool.OpenStringL(_L8("shortened"));
+    iStrRejected = stringPool.OpenStringL(_L8("rejected"));
+    iStrDeactivated = stringPool.OpenStringL(_L8("deactivated"));
+    iStrUnregistered = stringPool.OpenStringL(_L8("unregistered"));
+    iStrProbation = stringPool.OpenStringL(_L8("probation"));
+    iStrExpired = stringPool.OpenStringL(_L8("expired"));
+	// Subscriber
+	iSubscriber = CSIPRegEventSubscriber::NewL(iXMLParser,
+	                                           iConnection,
+	                                           iRegistrationContext,
+	                                           *iUserId,
+	                                           *this,aConfigExtension);
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::~CSIPRegEventHandler
+// -----------------------------------------------------------------------------
+//
+CSIPRegEventHandler::~CSIPRegEventHandler()
+	{
+	iDeltaTimer.Remove(iDeltaTimerEntry);
+	delete iSubscriber;
+	iStrFull.Close();
+	iStrActive.Close();
+	iStrTerminated.Close();
+    iStrShortened.Close();
+    iStrRejected.Close();
+    iStrDeactivated.Close();
+    iStrUnregistered.Close();
+    iStrProbation.Close();
+    iStrExpired.Close();
+	delete iUserId;
+	delete iLocalIP;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::SubscriptionFailedL
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::SubscriptionFailedL()
+    {
+    iObserver.RegEventSubscriptionFailedL();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::SubscriptionFailedL
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventHandler::SubscriptionFailedL(TInt aRetryAfter)
+    {
+    ReSubscribeAfterL(aRetryAfter);
+    iObserver.RegEventSubscriptionActive();
+    }
+		
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::RegEventNotSupportedByNetworkL
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//		
+void CSIPRegEventHandler::RegEventNotSupportedByNetworkL()
+    {
+    delete iSubscriber;
+    iSubscriber = NULL;
+    // The observer does not have to know that subscription failed,
+    // since in this case we are dealing with 
+    // IMS implentation that does not support reg-event and 
+    // the observer can consider the profile registered.
+    iObserver.RegEventSubscriptionActive();  
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ReRegister
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//   
+void CSIPRegEventHandler::ReRegister()
+    {
+    iObserver.ReRegister();
+    }    
+   
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::NotifyReceived
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventHandler::NotifyReceivedL(CSIPRegInfoElement& aNotifyData)
+    {
+    TBool terminated = EFalse;
+    if (iFirstNotifyProcessed)
+        {
+        if (aNotifyData.Version() == iRegEventVersion+1)
+            {
+            // process data
+            HandleRegInfoL(aNotifyData,terminated);
+            if (!terminated)
+                {
+                iRegEventVersion = aNotifyData.Version();
+                }
+            else
+                {
+                iRegEventVersion = 0;
+                }
+            }
+        else if (aNotifyData.Version() > iRegEventVersion+1)
+            {
+            // discard data and refresh subscription
+            iSubscriber->RefreshL();
+            iRegEventVersion = 0;
+            iFirstNotifyProcessed = EFalse;
+            }            
+        else  
+            {
+            // discard data: aNotifyData.Version() <= iRegEventVersion
+            }
+        }
+    else
+        {
+        if (aNotifyData.State() != iStrFull)
+            {
+            iSubscriber->RefreshL();
+            }
+        else
+            {
+            HandleRegInfoL(aNotifyData,terminated);
+            if (!terminated)
+                {
+                iRegEventVersion = aNotifyData.Version();
+                iFirstNotifyProcessed = ETrue;
+                iObserver.RegEventSubscriptionActive();              
+                }
+            }
+        }
+    }
+        
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::TerminatedL
+// From MSIPRegEventSubscriberObserver
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::TerminatedL(CSIPRegInfoElement& aNotifyData,
+                                      TInt aRetryAfter)
+    {
+    if (aRetryAfter < 0)
+        {
+        delete iSubscriber;
+        iSubscriber = NULL;  
+        iObserver.RegistrationTerminated();
+        }
+    else
+        {
+        if (AllLocalContactsTerminated(aNotifyData))
+            {
+            delete iSubscriber;
+            iSubscriber = NULL;  
+            iObserver.RegistrationTerminated();            
+            }
+        else
+            {
+            ReSubscribeAfterL(aRetryAfter);
+            }
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::SubscribeL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventHandler::SubscribeL()
+    {
+    if (iSubscriber)
+        {
+        iSubscriber->SubscribeL();
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::RefreshL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventHandler::RefreshL()
+    {
+    if (iSubscriber)
+        {
+        iSubscriber->RefreshL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HasTransaction
+// -----------------------------------------------------------------------------
+// 	    
+TBool CSIPRegEventHandler::HasTransaction(
+    const CSIPTransactionBase& aTransaction) const
+    {
+    if (iSubscriber)
+        {    
+        return iSubscriber->HasTransaction(aTransaction);
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HasTransaction
+// -----------------------------------------------------------------------------
+//
+TBool CSIPRegEventHandler::HasRefresh(const CSIPRefresh& aRefresh) const
+    {
+    if (iSubscriber)
+        {    
+        return iSubscriber->HasRefresh(aRefresh);
+        }
+    return EFalse;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HasDialog
+// -----------------------------------------------------------------------------
+//    
+TBool CSIPRegEventHandler::HasDialog(const CSIPDialog& aDialog) const
+    {
+    if (iSubscriber)
+        {
+        return iSubscriber->HasDialog(aDialog);
+        }
+    return EFalse;
+    }
+    	
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::RequestReceivedL
+// -----------------------------------------------------------------------------
+//	
+void CSIPRegEventHandler::RequestReceivedL(
+    CSIPServerTransaction* aTransaction,
+    CSIPDialog& aDialog)
+    {
+    if (iSubscriber)
+        {    
+        iSubscriber->RequestReceivedL(aTransaction,aDialog);
+        }
+    }
+	
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ResponseReceivedL
+// -----------------------------------------------------------------------------
+//					           
+void CSIPRegEventHandler::ResponseReceivedL(
+    CSIPClientTransaction& aTransaction)
+    {
+    if (iSubscriber)
+        {    
+        iSubscriber->ResponseReceivedL(aTransaction);
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ErrorOccured
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::ErrorOccured(
+    TInt aError,
+    CSIPTransactionBase& aTransaction)
+    {
+    if (iSubscriber)
+        {    
+        iSubscriber->ErrorOccured(aError,aTransaction);
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ErrorOccured
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventHandler::ErrorOccured(TInt aError,
+                                       CSIPDialog& aDialog)
+    {
+    if (iSubscriber)
+        {    
+        iSubscriber->ErrorOccured(aError,aDialog);
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ReSubscribeTimerExpired
+// A callback for CDeltaTimer
+// -----------------------------------------------------------------------------
+//    
+TInt CSIPRegEventHandler::ReSubscribeTimerExpired(TAny* aPtr)
+    {
+    CSIPRegEventHandler* self = reinterpret_cast<CSIPRegEventHandler*>(aPtr);
+    TRAP_IGNORE(self->ReSubscribeL())
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ReSubscribeAfterL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::ReSubscribeAfterL(TInt aRetryAfter)
+    {
+    if (aRetryAfter <= 0)
+        {
+        ReSubscribeL();
+        }
+    else
+        {
+        iDeltaTimer.Remove(iDeltaTimerEntry);
+        TTimeIntervalMicroSeconds32 interval(aRetryAfter*KMicroSecsInSec);
+        iDeltaTimer.Queue(interval,iDeltaTimerEntry);    
+        }
+    }
+ 
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::ReSubscribeL
+// -----------------------------------------------------------------------------
+//    
+void CSIPRegEventHandler::ReSubscribeL()
+    {
+    if (iSubscriber)
+        {
+        iSubscriber->ReSubscribeL();
+        iRegEventVersion = 0;
+        iFirstNotifyProcessed = EFalse;        
+        }                                    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HandleRegInfoL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::HandleRegInfoL(
+    CSIPRegInfoElement& aElement,
+    TBool& aTerminated)
+    {
+    aTerminated = EFalse;
+    TBool localIPFound = EFalse;
+    RPointerArray<CSIPRegistrationElement>& regElements =
+        aElement.RegistrationElements();
+        
+    for (TInt i=0; !aTerminated && i < regElements.Count(); i++)
+        {
+        CSIPRegistrationElement* element = regElements[i];
+        if (element)
+            {
+            HandleRegistrationElementL(*element,aTerminated,localIPFound);
+            }
+        }
+    if (!aTerminated && !localIPFound && aElement.State() == iStrFull)
+        {
+        aTerminated = ETrue;
+        if (iFirstNotifyProcessed)
+            {
+            iObserver.ReRegister();
+            }
+        else
+            {
+            iObserver.RegEventSubscriptionFailedL();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HandleRegistrationElementL
+// -----------------------------------------------------------------------------
+//
+void CSIPRegEventHandler::HandleRegistrationElementL(
+    CSIPRegistrationElement& aElement,
+    TBool& aTerminated,
+    TBool& aLocalIPFound)
+    {
+    aTerminated = EFalse;
+    TUint expirationTime = KMaxTUint;
+    TBool updateExpirationTime = EFalse;
+    RString registrationState = aElement.State();
+    RPointerArray<CSIPContactElement>& contacts = aElement.ContactElements();
+    for (TInt i=0; !aTerminated && i < contacts.Count(); i++)
+        {
+        CSIPContactElement* contact = contacts[i];
+        if (HasLocalIP(*contact))
+            {
+            aLocalIPFound = ETrue;
+            RString event = contact->Event();
+             // Network initiated RE-registration
+            if (registrationState == iStrActive &&
+                contact->State() == iStrActive &&
+                event == iStrShortened &&
+                contact->HasExpires())
+                {
+                updateExpirationTime = ETrue;
+                if (expirationTime > contact->Expires())
+                    {
+                    expirationTime = contact->Expires();
+                    }
+                }
+            // Network initiated DE-registration
+            TInt compareErr = aElement.AOR().Uri().Equivalent(iUserId->Uri());
+            if (compareErr == KErrNoMemory)
+                {
+                User::Leave(KErrNoMemory);
+                }
+            if (compareErr == KErrNone && contact->State() == iStrTerminated)
+                {
+                if (event == iStrRejected || 
+                    event == iStrTerminated ||
+                    event == iStrUnregistered ||
+                    event == iStrProbation)
+                    {
+                    iObserver.RegistrationTerminated();
+                    aTerminated = ETrue;
+                    }           
+                if (!aTerminated && 
+                    (event == iStrDeactivated || event == iStrExpired))
+                    {
+                    iObserver.RegistrationDeactivated();
+                    aTerminated = ETrue;
+                    }
+                }
+            }
+        }
+    if (!aTerminated && updateExpirationTime)
+        {
+        iObserver.ExpirationTimeUpdatedL(expirationTime);
+        }
+    }
+  
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::AllLocalContactsTerminated
+// -----------------------------------------------------------------------------
+//   
+TBool CSIPRegEventHandler::AllLocalContactsTerminated(
+    CSIPRegInfoElement& aNotifyData) const
+    {
+    TInt terminatedLocalContactCount = 0;
+    TInt localContactCount = 0;
+    
+    RPointerArray<CSIPRegistrationElement>& regElements =
+        aNotifyData.RegistrationElements();
+        
+    for (TInt i=0; i < regElements.Count(); i++)
+        {
+        RPointerArray<CSIPContactElement>& contacts = 
+            regElements[i]->ContactElements();
+        for (TInt j=0; j < contacts.Count(); j++)
+            {
+            CSIPContactElement* contact = contacts[j];
+            if (contact && HasLocalIP(*contact))
+                {
+                localContactCount++;
+                if (contact->State() == iStrTerminated)
+                    {
+                    terminatedLocalContactCount++;
+                    }
+                }
+            }
+        }
+        
+    if (localContactCount > 0 && 
+        localContactCount == terminatedLocalContactCount)
+        {
+        return ETrue;
+        }
+        
+    return EFalse;
+    }
+  
+// -----------------------------------------------------------------------------
+// CSIPRegEventHandler::HasLocalIP
+// -----------------------------------------------------------------------------
+//  
+TBool CSIPRegEventHandler::HasLocalIP(const CSIPContactElement& aContact) const
+    {
+    TPtrC8 host(aContact.Uri8().Uri().Extract(EUriHost));
+    return (host.CompareF(*iLocalIP) == 0);
+    }