Revision: 201025 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 15 Jul 2010 19:06:58 +0300
branchRCL_3
changeset 18 d746aee05493
parent 16 380473e13443
child 19 02ba3f1733c6
Revision: 201025 Kit: 2010127
supl/locationomasuplprotocolhandler/protocolhandler/src/epos_comasuplprotocolmanager.cpp
supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplposinitstate.cpp
supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplsession.cpp
supl/locationsuplfw/gateway/group/epos_csuplserver.mmp
supl/locationsuplfw/gateway/inc/epos_csuplsessionmanager.h
supl/locationsuplfw/gateway/inc/epos_csuplsessionrequest.h
supl/locationsuplfw/gateway/inc/epos_csuplsessionretryq.h
supl/locationsuplfw/gateway/src/epos_csuplsessionmanager.cpp
supl/locationsuplfw/gateway/src/epos_csuplsessionrequest.cpp
supl/locationsuplfw/gateway/src/epos_csuplsessionretryq.cpp
supl/locationsuplfw/protocolhandlerapi/bwins/epossuplprotocolhandlerpluginu.def
supl/locationsuplfw/protocolhandlerapi/eabi/epossuplprotocolhandlerpluginu.def
supl/locationsuplfw/protocolhandlerapi/inc/epos_csuplcommunicationmanager.h
supl/locationsuplfw/protocolhandlerapi/src/epos_csuplcommunicationmanager.cpp
--- a/supl/locationomasuplprotocolhandler/protocolhandler/src/epos_comasuplprotocolmanager.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationomasuplprotocolhandler/protocolhandler/src/epos_comasuplprotocolmanager.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -526,6 +526,10 @@
 		    {
 		    iOMASuplProtocolHandler1->HandleSuplMessageL(aSuplSession,aStatus,aMessage);
 		    }
+		else if (iOMASuplProtocolHandler2)
+				{
+				iOMASuplProtocolHandler2->HandleSuplMessageL(aSuplSession,aStatus,aMessage);
+				}
 		}
 	else if( major == 2 )
 		{
@@ -534,6 +538,10 @@
 		    {
 		    iOMASuplProtocolHandler2->HandleSuplMessageL(aSuplSession,aStatus,aMessage);
 		    }
+		else if (iOMASuplProtocolHandler1)
+				{
+				iOMASuplProtocolHandler1->HandleSuplMessageL(aSuplSession,aStatus,aMessage);
+				}
 		}
 	else
 		{
--- a/supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplposinitstate.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplposinitstate.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -605,7 +605,7 @@
 			}
 
 		// Position
-		if(iPosition)
+		if(iPosition && iRequestType == COMASuplSession::ESUPL_TERMINAL)
 			{
 			if(KErrNone == iPosition->Status() && !iIgnorePosData) //if iIgnorePosData is set do not use the pos data
 				{
--- a/supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplsession.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationomasuplprotocolhandler/protocolhandlerver1/src/epos_comasuplsession.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -465,7 +465,7 @@
 
     	if(aAllowedCapabilities == 0)
     		{
-    			iAllowedCapabilities = KGpsSETAssisted | KGpsSETBased | KAutonomousGps| KAFLT | KECID | KEOTD | KOTDOA | KCID; 
+				iAllowedCapabilities = KGpsSETBased | KAutonomousGps| KAFLT | KECID | KEOTD | KOTDOA | KCID; 
     		}
     	else
     		{
--- a/supl/locationsuplfw/gateway/group/epos_csuplserver.mmp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/gateway/group/epos_csuplserver.mmp	Thu Jul 15 19:06:58 2010 +0300
@@ -47,6 +47,7 @@
 SOURCE				epos_csuplserverstartuprequest.cpp
 SOURCE				epos_csuplconnecttimer.cpp
 SOURCE              epos_csuplecomeventwatcher.cpp
+SOURCE		    epos_csuplsessionretryq.cpp
 
 MW_LAYER_SYSTEMINCLUDE
 
--- a/supl/locationsuplfw/gateway/inc/epos_csuplsessionmanager.h	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/gateway/inc/epos_csuplsessionmanager.h	Thu Jul 15 19:06:58 2010 +0300
@@ -26,6 +26,8 @@
 #include <epos_suplterminal.h>
 #include <epos_suplterminaltrigger.h>
 #include "epos_csuplecomeventwatcher.h"
+#include "epos_csuplsessionretryq.h"
+#include "epos_csuplcommunicationmanager.h"
 
 // FORWARD DECLARATIONS
 class CSUPLProtocolManagerBase;
@@ -37,7 +39,7 @@
 /**
 *  Class to handle SUPL sessions 
 */
-class CSuplSessionManager : public CBase
+class CSuplSessionManager : public CBase, MSuplConnectionMonitor
 	{
     public:  // Constructors and destructor
 
@@ -67,6 +69,9 @@
         void DeInitialize(TRequestStatus& aStatus);
         void CancelDeInitialize();
 
+		void QueueForReIssueRequestL(CSuplSessionRequest& aSessionRequest);
+		void RemoveFromQueueForReIssueRequest(CSuplSessionRequest& aSessionRequest);
+
 		void StartTriggerSessionL(
 				CSuplSessionBase* aSuplSession,
 				TRequestStatus& aStatus,
@@ -86,7 +91,11 @@
         	);
 		
 		TInt GetSUPLMessageVersionL(TInt& aMajorVersion, const TDesC8& aReceivedMessage);
-		
+
+		// from MSuplConnectionMonitor
+		void ConnectionOpened();
+		void ConnectionClosed();
+	
     private:
 
         /**
@@ -110,7 +119,7 @@
         CSuplCommunicationManager*  iCommMgr;
         TInt iConnectError;
         CSuplEcomEventWatcher*      iEcomWatcher;
-
+		CSuplSessionRetryQ*			iSessionRetryQ;
     };
 
 
--- a/supl/locationsuplfw/gateway/inc/epos_csuplsessionrequest.h	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/gateway/inc/epos_csuplsessionrequest.h	Thu Jul 15 19:06:58 2010 +0300
@@ -33,6 +33,8 @@
 // FORWARD DECLARATIONS
 class MSuplSessionObserver;
 class MNetInitiatedObserver;
+class CSuplSessionManager;
+class CSuplSessionBase;
 // CLASS DECLARATION
 
 /**
@@ -99,6 +101,7 @@
 		void CancelTriggerringRequest();
 		
 		void ProtocolHUnloaded();
+		void ReIssueRequestL();
 		
     protected:  // From CActive
 
@@ -129,7 +132,9 @@
             ESuplForwardMessage,
             ESuplStartTriggerRequest,            
             ESuplStopTriggerRequest,
-            ESuplTriggerFiredNotifyRequest
+            ESuplTriggerFiredNotifyRequest,
+			ESuplWaitingToRetrySession,
+			ESuplRetryingSession
             };
      
 	 TSuplRequestStage           iRequestPhase;
@@ -139,6 +144,17 @@
   	 CSuplSessionManager& 		 iSessnMgr;
 	 CSuplSessionBase*			 iSuplSessn;
 	 TInt iHandle;
+
+	 CSuplSessionBase* iParamSuplSessn;
+	 TInt iParamSetCaps;
+	 TInt iParamReqId;
+	 TBool iParamFallback;
+	 TBool iParamFirstReq;
+	 TBool iParamExtendedQopUsed;
+	 TSuplTerminalQop iParamQop;
+	 HBufC* iParamExtendedFallback;
+	 
+	 TBool iSessionStarted;
     };  
 
 #endif  // __CSuplSessionRequest_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/supl/locationsuplfw/gateway/inc/epos_csuplsessionretryq.h	Thu Jul 15 19:06:58 2010 +0300
@@ -0,0 +1,72 @@
+/*
+* ==============================================================================
+*  Name        : epos_csuplsessionretryq.h
+*  Part of     : SUPL Framework / SUPL Server
+*  Interface   : --
+*  Description : Class to handle retries of failed requests. It waits for all the current sessions to end and then
+*  				 notifies the failed sessions that they can retry.
+*  Version     :
+*
+*  Copyright (c) 2010 Nokia Corporation.
+*  This material, including documentation and any related
+*  computer programs, is protected by copyright controlled by
+*  Nokia Corporation. All rights are reserved. Copying,
+*  including reproducing, storing, adapting or translating, any
+*  or all of this material requires the prior written consent of
+*  Nokia Corporation. This material also contains confidential
+*  information which may not be disclosed to others without the
+*  prior written consent of Nokia Corporation.
+* ==============================================================================
+*/
+
+#ifndef EPOS_CSUPLSESSIONRETRYQ_H
+#define EPOS_CSUPLSESSIONRETRYQ_H
+
+// INCLUDES
+#include <e32base.h>
+
+// CLASS DECLARATION
+class CSuplSessionRequest;
+
+/**
+ * Class to handle retries of failed requests. It waits for all the current sessions to end and then
+ *		 notifies the failed sessions that they can retry.
+ */
+class CSuplSessionRetryQ : public CTimer
+    {
+    public:
+        static CSuplSessionRetryQ* NewL();
+		~CSuplSessionRetryQ();
+
+        void AddToQueueL(CSuplSessionRequest& aSessionRequest);
+        void RemoveFromQueueL(CSuplSessionRequest& aSessionRequest);
+		void SessionStarted();
+		void SessionEnded();
+
+    private:
+		CSuplSessionRetryQ();
+        void ConstructL();
+
+        // By default, prohibit copy constructor
+        CSuplSessionRetryQ( const CSuplSessionRetryQ& );
+        // Prohibit assigment operator
+        CSuplSessionRetryQ& operator= ( const CSuplSessionRetryQ& );
+
+    protected:  // Functions from base classes
+
+        /**
+        * From CActive.
+        * Called when timer completes
+        */
+        void RunL();
+
+    private:    // Data
+		RPointerArray<CSuplSessionRequest> iSessionRequests;
+		TInt iSessionCount;
+		TBool iSomeSessionEnded;
+		TTime iTimeOfLastEndedSession;
+    };
+
+#endif // EPOS_CSUPLSESSIONRETRYQ_H
+
+// End of File
--- a/supl/locationsuplfw/gateway/src/epos_csuplsessionmanager.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/gateway/src/epos_csuplsessionmanager.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -49,7 +49,8 @@
 void CSuplSessionManager::ConstructL()
     {
     DEBUG_TRACE("CSuplSessionManager::ConstructL", __LINE__)            
-    iCommMgr = CSuplCommunicationManager::NewL();
+	iSessionRetryQ = CSuplSessionRetryQ::NewL();
+    iCommMgr = CSuplCommunicationManager::NewL(*this);
     iCommMgr->Initialize();
     iConnectError=KErrNone;
     }
@@ -72,6 +73,7 @@
     if(iProtocolMgr)          
     delete iProtocolMgr;
     delete iCommMgr;
+	delete iSessionRetryQ;
     delete iEcomWatcher;
     REComSession::FinalClose();
     }
@@ -465,5 +467,26 @@
 		User::RequestComplete(status,KErrNotReady);
 		}	
 	}
+	
+void CSuplSessionManager::ConnectionOpened()
+	{
+	iSessionRetryQ->SessionStarted();	
+	}
+
+void CSuplSessionManager::ConnectionClosed()
+	{
+	iSessionRetryQ->SessionEnded();	
+	}
+
+
+void CSuplSessionManager::QueueForReIssueRequestL(CSuplSessionRequest& aSessionRequest)
+	{
+	iSessionRetryQ->AddToQueueL(aSessionRequest);
+	}
+
+void CSuplSessionManager::RemoveFromQueueForReIssueRequest(CSuplSessionRequest& aSessionRequest)
+	{
+	iSessionRetryQ->RemoveFromQueueL(aSessionRequest);
+	}	
     
 // End of File
--- a/supl/locationsuplfw/gateway/src/epos_csuplsessionrequest.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/gateway/src/epos_csuplsessionrequest.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -49,7 +49,8 @@
     iRequestPhase(ESuplReqInactive),
     iObserver(aObserver),
     iSessnMgr(aSessnMgr),
-    iSuplSessn(aSuplSessn)    
+    iSuplSessn(aSuplSessn),
+    iParamExtendedFallback(NULL)
     {
     DEBUG_TRACE("CSuplSessionRequest::CSuplSessionRequest", __LINE__)
     CActiveScheduler::Add(this);
@@ -60,7 +61,8 @@
     iRequestPhase(ESuplReqInactive),
     iNetObserver(aObserver),
     iSessnMgr(aSessnMgr),
-    iSuplSessn(aSuplSessn)
+    iSuplSessn(aSuplSessn),
+    iParamExtendedFallback(NULL)    
     {
     DEBUG_TRACE("CSuplSessionRequest::CSuplSessionRequest", __LINE__)
     CActiveScheduler::Add(this);
@@ -95,6 +97,11 @@
 CSuplSessionRequest::~CSuplSessionRequest()
     {
     DEBUG_TRACE("CSuplSessionRequest::~CSuplSessionRequest", __LINE__)
+    iSessnMgr.RemoveFromQueueForReIssueRequest(*this);
+    
+    if (iParamExtendedFallback)
+        delete iParamExtendedFallback;
+    
 	if (IsActive())      
       	Cancel();
     }
@@ -115,6 +122,13 @@
 	
 	iSessnMgr.RunSuplSessionL(aSuplSessn, iStatus, aHslpAddress, fallBack, aSetCaps, aReqId, aFirstReq);
 	SetActive();
+	iSessionStarted = ETrue;
+	iParamFallback = ETrue;
+	iParamSuplSessn = aSuplSessn;
+	iParamSetCaps = aSetCaps;
+	iParamReqId = aReqId;
+	iParamFirstReq = aFirstReq;
+	iParamExtendedQopUsed = EFalse;
     }
 // ---------------------------------------------------------
 // CSuplSessionRequest::MakeSuplSessionRequestL
@@ -132,6 +146,15 @@
 	
 	iSessnMgr.RunSuplSessionL(aSuplSessn, iStatus, aHslpAddress, fallBack, aSetCaps, aReqId, aQop, aFirstReq);
 	SetActive();
+	
+	iSessionStarted = ETrue;
+    iParamFallback = ETrue;
+	iParamSuplSessn = aSuplSessn;
+	iParamSetCaps = aSetCaps;
+	iParamReqId = aReqId;
+	iParamFirstReq = aFirstReq;
+	iParamQop = aQop;	
+	iParamExtendedQopUsed = ETrue;	
     }
 
 void CSuplSessionRequest::MakeSuplSessionRequestL(CSuplSessionBase* aSuplSessn,const TDesC& aHslpAddress, TBool aFallBack, TInt aSetCaps, TInt aReqId, TBool aFirstReq)
@@ -141,6 +164,21 @@
     iStatus = KRequestPending;
     iSessnMgr.RunSuplSessionL(aSuplSessn, iStatus, aHslpAddress, aFallBack, aSetCaps, aReqId, aFirstReq);
 	SetActive();
+	
+	iSessionStarted = ETrue;
+    iParamFallback = aFallBack;
+	iParamSuplSessn = aSuplSessn;
+	iParamSetCaps = aSetCaps;
+	iParamReqId = aReqId;
+	iParamFirstReq = aFirstReq;
+    if (iParamExtendedFallback)
+        {
+        delete iParamExtendedFallback;
+        iParamExtendedFallback = NULL;
+        }
+	iParamExtendedFallback = HBufC::NewL(aHslpAddress.Length());
+	*iParamExtendedFallback = aHslpAddress;
+	iParamExtendedQopUsed = EFalse;	
     }
 
 void CSuplSessionRequest::MakeSuplSessionRequestL(CSuplSessionBase* aSuplSessn,const TDesC& aHslpAddress, TBool aFallBack, TInt aSetCaps, TInt aReqId, TSuplTerminalQop& aQop, TBool aFirstReq)
@@ -150,6 +188,22 @@
     iStatus = KRequestPending;
     iSessnMgr.RunSuplSessionL(aSuplSessn, iStatus, aHslpAddress, aFallBack, aSetCaps, aReqId, aQop, aFirstReq);
     SetActive();
+	
+	iSessionStarted = ETrue;
+    iParamFallback = aFallBack;
+	iParamSuplSessn = aSuplSessn;
+	iParamSetCaps = aSetCaps;
+	iParamReqId = aReqId;
+	iParamFirstReq = aFirstReq;
+    iParamQop = aQop;   
+    iParamExtendedQopUsed = ETrue;
+    if (iParamExtendedFallback)
+        {
+        delete iParamExtendedFallback;
+        iParamExtendedFallback = NULL;
+        }
+    iParamExtendedFallback = HBufC::NewL(aHslpAddress.Length());
+    *iParamExtendedFallback = aHslpAddress;
     }  
     
 // ---------------------------------------------------------
@@ -198,6 +252,7 @@
     if (IsActive())
         {
 		iObserver->CompleteRunSession(KErrServerTerminated);
+		iSessionStarted = EFalse;
         Cancel();
         }
     }
@@ -212,44 +267,85 @@
     {
     DEBUG_TRACE("CSuplSessionRequest::RunL", __LINE__)
     TInt err = iStatus.Int();
-    switch (iRequestPhase)
-        {
-        case ESuplStartTriggerRequest:
-        case ESuplStopTriggerRequest:
-        	{
-			iRequestPhase = ESuplReqInactive;
-			iObserver->CompleteTriggerRunSession(err);			
-        	break;
-        	}
-        case ESuplTriggerFiredNotifyRequest:
-        	{
-			iRequestPhase = ESuplReqInactive;
-			iObserver->CompleteTriggerFiredNotifyRequest(err);			
-        	break;
-        	}
-        case ESuplSessionRequest:
+	
+	iSessionStarted = EFalse;
+	if(err != KErrNone && iRequestPhase == ESuplSessionRequest)
+		{
+		DEBUG_TRACE("Retrying session", __LINE__)
+		iRequestPhase = ESuplWaitingToRetrySession;
+		iSessnMgr.QueueForReIssueRequestL(*this);
+		}
+	else
+		{	
+	    switch (iRequestPhase)
+	        {
+	        case ESuplStartTriggerRequest:
+	        case ESuplStopTriggerRequest:
+	        	{
+				iRequestPhase = ESuplReqInactive;
+				iObserver->CompleteTriggerRunSession(err);			
+	        	break;
+	        	}
+	        case ESuplTriggerFiredNotifyRequest:
+	        	{
+				iRequestPhase = ESuplReqInactive;
+				iObserver->CompleteTriggerFiredNotifyRequest(err);			
+	        	break;
+	        	}
+	        case ESuplSessionRequest:
+			case ESuplRetryingSession:
+	            {
+				iRequestPhase = ESuplReqInactive;
+				iObserver->CompleteRunSession(err);
+	            break;
+	            }
+	       case ESuplCancelRunSessionRequest:
+	            {
+				iRequestPhase = ESuplReqInactive;
+				iObserver->CompleteRunSession(err);
+	            break;
+	            }
+	        case ESuplForwardMessage:
+	        	{	
+	        	iRequestPhase = ESuplReqInactive;
+	        	iNetObserver->CompleteForwardMessageL(iHandle);
+	        	break;
+	        	}
+
+	        default :
+	            DebugPanic(EPosSuplServerPanicRequestInconsistency);
+	        }
+		}
+    }
+
+void CSuplSessionRequest::ReIssueRequestL()
+	{
+	DEBUG_TRACE("CSuplSessionRequest::ReIssueRequestL", __LINE__)
+	if(!iParamExtendedQopUsed)
+		{
+        if (!iParamExtendedFallback)
             {
-			iRequestPhase = ESuplReqInactive;
-			iObserver->CompleteRunSession(err);
-            break;
+            MakeSuplSessionRequestL(iParamSuplSessn, iParamSetCaps, iParamReqId, iParamFirstReq);
             }
-       case ESuplCancelRunSessionRequest:
+        else
             {
-			iRequestPhase = ESuplReqInactive;
-			iObserver->CompleteRunSession(err);
-            break;
+            MakeSuplSessionRequestL(iParamSuplSessn, *iParamExtendedFallback, iParamFallback, iParamSetCaps, iParamReqId, iParamFirstReq);
             }
-        case ESuplForwardMessage:
-        	{	
-        	iRequestPhase = ESuplReqInactive;
-        	iNetObserver->CompleteForwardMessageL(iHandle);
-        	break;
-        	}
-
-        default :
-            DebugPanic(EPosSuplServerPanicRequestInconsistency);
-        }
-    }
+		}
+	else
+		{
+        if (!iParamExtendedFallback)
+            {
+            MakeSuplSessionRequestL(iParamSuplSessn, iParamSetCaps, iParamReqId, iParamQop, iParamFirstReq);
+            }
+        else
+            {
+            MakeSuplSessionRequestL(iParamSuplSessn, *iParamExtendedFallback, iParamFallback, iParamSetCaps, iParamReqId, iParamQop, iParamFirstReq);
+            }
+		}
+	DEBUG_TRACE("Retry request succesfull", __LINE__)
+	iRequestPhase = ESuplRetryingSession;
+	}
 
 // ---------------------------------------------------------
 // CSuplSessionRequest::RunError
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/supl/locationsuplfw/gateway/src/epos_csuplsessionretryq.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -0,0 +1,185 @@
+/*
+* ==============================================================================
+*  Name        : epos_csuplsessionretryq.cpp
+*  Part of     : SUPL Framework / SUPL Server
+*  Description : Class to handle retries of failed requests. It waits for all the current sessions to end and then
+*  				 notifies the failed sessions that they can retry.
+*  Version     :
+*
+*  Copyright (c) 2010 Nokia Corporation.
+*  This material, including documentation and any related
+*  computer programs, is protected by copyright controlled by
+*  Nokia Corporation. All rights are reserved. Copying,
+*  including reproducing, storing, adapting or translating, any
+*  or all of this material requires the prior written consent of
+*  Nokia Corporation. This material also contains confidential
+*  information which may not be disclosed to others without the
+*  prior written consent of Nokia Corporation.
+* ==============================================================================
+*/
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <e32debug.h>
+
+#include "epos_csuplsessionretryq.h"
+#include "epos_csuplsessionrequest.h"
+#include "epos_csuplglobal.h"
+
+//#ifdef _DEBUG
+_LIT(KTraceFileName, "SUPL_GW::epos_csuplsessionretryq.cpp");
+//#endif
+
+// CONSTANTS
+const TTimeIntervalSeconds KRecentConnectionInterval(5);
+const TTimeIntervalMicroSeconds32 KSmallDelay(2000000);
+const TTimeIntervalMicroSeconds32 KReissueRequestDelay(5000000);
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CSuplSessionRetryQ::CSuplSessionRetryQ()
+    : CTimer(EPriorityNormal)
+    {
+    DEBUG_TRACE("CSuplSessionRetryQ", __LINE__)
+    CActiveScheduler::Add(this);
+    }
+
+// Destructor
+CSuplSessionRetryQ::~CSuplSessionRetryQ()
+    {
+    DEBUG_TRACE("~CSuplSessionRetryQ", __LINE__)
+    Cancel();
+	iSessionRequests.Close();
+    }
+
+// Two-phased constructor
+CSuplSessionRetryQ* CSuplSessionRetryQ::NewL()
+    {
+    DEBUG_TRACE("NewL", __LINE__)
+    CSuplSessionRetryQ* self = new (ELeave) CSuplSessionRetryQ();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// EPOC default constructor
+void CSuplSessionRetryQ::ConstructL()
+    {
+    DEBUG_TRACE("ConstructL", __LINE__)
+    CTimer::ConstructL();
+    }
+
+
+void CSuplSessionRetryQ::AddToQueueL(CSuplSessionRequest& aSessionRequest)
+	{
+    TBuf<256> msg(_L("AddToQueueL, count = "));
+    msg.AppendNum(iSessionRequests.Count()+1);
+    SuplGlobal::Trace(msg, KTraceFileName, __LINE__);   
+	// if there is no open connection and there is nothing else in the queue then check when it's possible to 
+	// re-issue, otherwise just leave in the queue
+    if(iSessionRequests.Count() == 0 && iSessionCount == 0)
+		{
+		TTime now;
+		now.UniversalTime();
+		// if there was some recent connection made that was closed then ask for re-issue straight away
+		if(iSomeSessionEnded && now - KRecentConnectionInterval < iTimeOfLastEndedSession)
+			{
+			DEBUG_TRACE("Re-issuing request straight away", __LINE__)
+			RDebug::Printf("[LBS][SUPL]Re-issuing request straight away");	
+			After(KSmallDelay);
+			}
+		// if there is no previous request then wait a little before re-issuing request
+		else
+			{
+			DEBUG_TRACE("Re-issuing request after a delay", __LINE__)
+			RDebug::Printf("[LBS][SUPL]Re-issuing request after a delay");	
+			After(KReissueRequestDelay);
+			}
+		}
+	iSessionRequests.AppendL(&aSessionRequest);
+	}
+
+void CSuplSessionRetryQ::RemoveFromQueueL(CSuplSessionRequest& aSessionRequest)
+	{
+	TInt index = 0;
+	index = iSessionRequests.Find(&aSessionRequest);
+	if(index != KErrNotFound)
+		{
+		iSessionRequests.Remove(index);
+		
+	    TBuf<256> msg(_L("Removed from queue, count = "));
+	    msg.AppendNum(iSessionRequests.Count());
+	    SuplGlobal::Trace(msg, KTraceFileName, __LINE__);   
+		
+		}
+	}
+
+void CSuplSessionRetryQ::SessionStarted()
+	{
+    ++iSessionCount;
+
+    
+    TBuf<256> msg(_L("SessionStarted, session count = "));
+    msg.AppendNum(iSessionCount);
+    SuplGlobal::Trace(msg, KTraceFileName, __LINE__);   
+	}
+
+void CSuplSessionRetryQ::SessionEnded()
+	{
+	--iSessionCount;
+	
+    TBuf<256> msg(_L("SessionEnded, session count = "));
+    msg.AppendNum(iSessionCount);
+    SuplGlobal::Trace(msg, KTraceFileName, __LINE__);   
+	
+	
+	if(iSessionCount == 0 && iSessionRequests.Count() > 0)
+		{
+		DEBUG_TRACE("Re-issuing request straight away", __LINE__)
+		After(KSmallDelay);
+		}
+	// If a connection just closed remember the time-stamp so later it can be decided when to re-issue
+	iSomeSessionEnded = ETrue;
+	iTimeOfLastEndedSession.UniversalTime();
+	}
+
+// ---------------------------------------------------------
+// CSuplSessionRetryQ::RunL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CSuplSessionRetryQ::RunL()
+    {
+    TBuf<256> msg(_L("RunL, session count = "));
+    msg.AppendNum(iSessionCount);
+    msg.Append(_L(", queue count = "));
+    msg.AppendNum(iSessionRequests.Count());
+    SuplGlobal::Trace(msg, KTraceFileName, __LINE__);   
+   
+	// If a connection is already open, wait until it finishes
+	if(iSessionCount == 0 && iSessionRequests.Count() > 0)
+		{
+		DEBUG_TRACE("Re-issuing request now", __LINE__)
+		// re-issue request for the first item in the queue
+		TRAPD(err, iSessionRequests[0]->ReIssueRequestL());
+		while(err!=KErrNone && iSessionRequests.Count() > 1)
+			{
+			// if for some reason re-issuing doesn't work then just try the next requestor and forget about the first one
+			DEBUG_TRACE("Re-issue failed, trying next one in the queue", __LINE__)
+			iSessionRequests.Remove(0);
+			TRAP(err, iSessionRequests[0]->ReIssueRequestL());
+			}
+		if(err!=KErrNone)
+			{
+			DEBUG_TRACE("Re-issue failed", __LINE__)
+			}
+		iSessionRequests.Remove(0);
+		}
+    }
+
+
--- a/supl/locationsuplfw/protocolhandlerapi/bwins/epossuplprotocolhandlerpluginu.def	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/protocolhandlerapi/bwins/epossuplprotocolhandlerpluginu.def	Thu Jul 15 19:06:58 2010 +0300
@@ -13,9 +13,9 @@
 	?Initialize@CSuplCommunicationManager@@QAEHXZ @ 12 NONAME ; int CSuplCommunicationManager::Initialize(void)
 	?GetLocalIPAddress@CSuplConnection@@QAEHAAVTInetAddr@@@Z @ 13 NONAME ; int CSuplConnection::GetLocalIPAddress(class TInetAddr &)
 	?NewL@CSUPLProtocolManagerBase@@SAPAV1@ABVTDesC8@@@Z @ 14 NONAME ; class CSUPLProtocolManagerBase * CSUPLProtocolManagerBase::NewL(class TDesC8 const &)
-	?NewL@CSuplCommunicationManager@@SAPAV1@XZ @ 15 NONAME ; class CSuplCommunicationManager * CSuplCommunicationManager::NewL(void)
-	?Send@CSuplConnection@@QAEXABVTDesC8@@AAVTRequestStatus@@@Z @ 16 NONAME ; void CSuplConnection::Send(class TDesC8 const &, class TRequestStatus &)
-	?CreateConnectionL@CSuplCommunicationManager@@QAEPAVCSuplConnection@@ABVTDesC16@@HHIH@Z @ 17 NONAME ; class CSuplConnection * CSuplCommunicationManager::CreateConnectionL(class TDesC16 const &, int, int, unsigned int, int)
+	?Send@CSuplConnection@@QAEXABVTDesC8@@AAVTRequestStatus@@@Z @ 15 NONAME ; void CSuplConnection::Send(class TDesC8 const &, class TRequestStatus &)
+	?CreateConnectionL@CSuplCommunicationManager@@QAEPAVCSuplConnection@@ABVTDesC16@@HHIH@Z @ 16 NONAME ; class CSuplConnection * CSuplCommunicationManager::CreateConnectionL(class TDesC16 const &, int, int, unsigned int, int)
+	?NewL@CSuplCommunicationManager@@SAPAV1@AAVMSuplConnectionMonitor@@@Z @ 17 NONAME ; class CSuplCommunicationManager * CSuplCommunicationManager::NewL(class MSuplConnectionMonitor &)
 	?CloseConnection@CSuplConnection@@QAEXXZ @ 18 NONAME ; void CSuplConnection::CloseConnection(void)
 	?CancelConnect@CSuplConnection@@QAEXAAVTRequestStatus@@@Z @ 19 NONAME ; void CSuplConnection::CancelConnect(class TRequestStatus &)
 	?DestroyConnection@CSuplCommunicationManager@@QAEHPAVCSuplConnection@@@Z @ 20 NONAME ; int CSuplCommunicationManager::DestroyConnection(class CSuplConnection *)
--- a/supl/locationsuplfw/protocolhandlerapi/eabi/epossuplprotocolhandlerpluginu.def	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/protocolhandlerapi/eabi/epossuplprotocolhandlerpluginu.def	Thu Jul 15 19:06:58 2010 +0300
@@ -21,7 +21,7 @@
 	_ZN25CSuplCommunicationManager17CreateConnectionLERK7TDesC16ji @ 20 NONAME
 	_ZN25CSuplCommunicationManager17DestroyConnectionEP15CSuplConnection @ 21 NONAME
 	_ZN25CSuplCommunicationManager17SetPacketReceiverEP19MSuplPacketReceiver @ 22 NONAME
-	_ZN25CSuplCommunicationManager4NewLEv @ 23 NONAME
+	_ZN25CSuplCommunicationManager4NewLER22MSuplConnectionMonitor @ 23 NONAME
 	_ZN25CSuplCommunicationManagerD0Ev @ 24 NONAME
 	_ZN25CSuplCommunicationManagerD1Ev @ 25 NONAME
 	_ZN25CSuplCommunicationManagerD2Ev @ 26 NONAME
--- a/supl/locationsuplfw/protocolhandlerapi/inc/epos_csuplcommunicationmanager.h	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/protocolhandlerapi/inc/epos_csuplcommunicationmanager.h	Thu Jul 15 19:06:58 2010 +0300
@@ -36,6 +36,13 @@
 
 // CLASS DECLARATION
 
+class MSuplConnectionMonitor
+	{
+public:
+	virtual void ConnectionOpened() = 0;
+	virtual void ConnectionClosed() = 0;
+	};
+
 /**
 *  CSuplCommunicationManager is the Singleton that provides SUPL Connection 
 *  to be used by Protocol Handler
@@ -54,7 +61,7 @@
         /**
         * Two-phased constructor.
         */
-        IMPORT_C static CSuplCommunicationManager* NewL();
+        IMPORT_C static CSuplCommunicationManager* NewL(MSuplConnectionMonitor& aConnMonitor);
         
         /**
         * Destructor.
@@ -178,7 +185,7 @@
         /**
         * C++ default constructor.
         */
-        CSuplCommunicationManager();
+        CSuplCommunicationManager(MSuplConnectionMonitor& aConnMonitor);
 
         /**
         * By default Symbian 2nd phase constructor is private.
@@ -206,6 +213,8 @@
         
         // Trace Log
         CSuplConnTrace* iTrace;
+        
+        MSuplConnectionMonitor& iConnMonitor;
     };
 
 #endif      // C_CSUPLCOMMUNICATIONMANAGER_H   
--- a/supl/locationsuplfw/protocolhandlerapi/src/epos_csuplcommunicationmanager.cpp	Mon Jun 21 16:08:35 2010 +0300
+++ b/supl/locationsuplfw/protocolhandlerapi/src/epos_csuplcommunicationmanager.cpp	Thu Jul 15 19:06:58 2010 +0300
@@ -36,8 +36,8 @@
 
 // ============================ MEMBER FUNCTIONS ===============================
 
-CSuplCommunicationManager::CSuplCommunicationManager():
-	iServerConnected(EFalse)
+CSuplCommunicationManager::CSuplCommunicationManager(MSuplConnectionMonitor& aConnMonitor):
+	iServerConnected(EFalse), iConnMonitor(aConnMonitor)
     {
     }
 
@@ -49,9 +49,9 @@
 	iTrace->Trace(_L("CSuplCommunicationManager::ConstructL"), KTraceFileName, __LINE__); 
     }
 
-EXPORT_C CSuplCommunicationManager* CSuplCommunicationManager::NewL()
+EXPORT_C CSuplCommunicationManager* CSuplCommunicationManager::NewL(MSuplConnectionMonitor& aConnMonitor)
     {
-    CSuplCommunicationManager* self = new( ELeave ) CSuplCommunicationManager;
+    CSuplCommunicationManager* self = new( ELeave ) CSuplCommunicationManager(aConnMonitor);
     
     CleanupStack::PushL( self );
     self->ConstructL();
@@ -127,7 +127,8 @@
     	suplConnection = CSuplConnection::NewL(iSocketServ, aHostAddress, aPort, aIAPId, this);	
     	iConnArray.Append(suplConnection);
     	iTrace->Trace(_L("CSuplCommunicationManager::CreateConnectionL New Connection Created"), KTraceFileName, __LINE__);
-    	}
+    	iConnMonitor.ConnectionOpened();
+    }
     else
     	{
     	// Check if we have exceeded the max no. of sessions 
@@ -140,8 +141,9 @@
     		suplConnection = CSuplConnection::NewL(iSocketServ, aHostAddress, aPort, aIAPId, this);
     		iConnArray.Append(suplConnection);
     		iTrace->Trace(_L("CSuplCommunicationManager::CreateConnectionL New Connection Created"), KTraceFileName, __LINE__);
-    		}
+        	iConnMonitor.ConnectionOpened();
     	}
+    }
     
     // Increment the Ref Count
     suplConnection->IncRefCount();
@@ -181,6 +183,7 @@
     	{
         suplConnection = CSuplConnection::NewL(iSocketServ, aHostAddress, aPort, aIAPId, aTls, aPskTls, this); 
         iConnArray.Append(suplConnection);
+       	iConnMonitor.ConnectionOpened();
         iTrace->Trace(_L("CSuplCommunicationManager::CreateConnectionL New Connection Created"), KTraceFileName, __LINE__);
     	}
     else
@@ -194,6 +197,7 @@
         	{
             suplConnection = CSuplConnection::NewL(iSocketServ, aHostAddress, aPort, aIAPId, aTls, aPskTls, this);
             iConnArray.Append(suplConnection);
+        	iConnMonitor.ConnectionOpened();
             iTrace->Trace(_L("CSuplCommunicationManager::CreateConnectionL New Connection Created"), KTraceFileName, __LINE__);
         	}
     	}
@@ -243,6 +247,8 @@
     iTrace->Trace(_L("CSuplCommunicationManager::DestroyConnection Destroy Connection"), KTraceFileName, __LINE__);
     aConnection->Destroy();
     
+    iConnMonitor.ConnectionClosed();
+    
     return KErrNone;
     }