supl/locationsuplfw/gateway/src/epos_csuplsessionretryq.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 19 Aug 2010 10:20:18 +0300
branchRCL_3
changeset 19 02ba3f1733c6
parent 18 d746aee05493
child 20 2b4ea9893b66
permissions -rw-r--r--
Revision: 201030 Kit: 201033

/*
* ==============================================================================
*  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__)
		if( !IsActive() )
		    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);
		}
    }