locationmgmt/agpslocationmgr/src/lbsnetworkgatewayhandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:50:39 +0200
changeset 0 9cfd9a3ee49c
permissions -rw-r--r--
Revision: 201002 Kit: 201005

// Copyright (c) 2006-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:
//


#include "lbsnetworkgatewayhandler.h"
#include "lbsassistancedatacacheapi.h"
#include <lbs/lbsassistancealmanac.h>
#include <lbs/lbsassistancebadsatlist.h>
#include <lbs/lbsassistanceaquisitionassistance.h>
#include <lbs/lbsassistancenavigationmodel.h>
#include <lbs/lbsassistancereferencetime.h>
#include <lbs/lbsassistanceionosphericmodel.h>
#include <lbs/lbsassistanceutcmodel.h>
#include <lbs/lbsassistancereferencelocation.h>
#include "lbscommoninternaldatatypes.h"
#include "lbsagpsngmsgs.h"
#include "lbsdevloggermacros.h"
#include <lbs/lbslocerrors.h>


// We can queue up to 4 messages
const TInt KNetworkGatewayHandlerQSize = 4;


CNetworkGatewayHandler * CNetworkGatewayHandler::NewL
	(
	MNetworkGatewayHandlerObserver* aObserver
	)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::NewL()");
	CNetworkGatewayHandler * self = new(ELeave) CNetworkGatewayHandler (aObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop();
	return self;
	}
	
CNetworkGatewayHandler::CNetworkGatewayHandler(MNetworkGatewayHandlerObserver* aObserver) : 
	CActive(EPriorityStandard),
	iObserver(aObserver),
	iQ(KNetworkGatewayHandlerQSize)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::CNetworkGatewayHandler()");
	}

void CNetworkGatewayHandler::ConstructL()
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::ConstructL()");
	CActiveScheduler::Add(this);
	iAssistanceDataCache.OpenL();
	iNGChannel.OpenL(RLbsNetChannel::EChannelAGPS2NG, *this);
	iQ.OpenL();
	}

//------------------------------------------------------------------------------------------------------------
CNetworkGatewayHandler::~CNetworkGatewayHandler()
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::~CNetworkGatewayHandler()");
	iAssistanceDataCache.Close(); 
	iNGChannel.Close();
	iQ.Close();
	}

 // request from integration module to read a particular  assistance data item
TInt CNetworkGatewayHandler::GetAssistanceDataItem(TLbsAssistanceDataItem aItem,RDataReaderRootBase& aDataRoot,	TTime& aTimeStamp)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::GetAssistanceDataItem()");
	TInt error = iAssistanceDataCache.GetAssistDataItem(aItem,aDataRoot);
	if (KErrNone == error)
		{
		TBool dataAvailable = EFalse;
		switch(aItem)
        	{
	        case EAssistanceDataAquisitionAssistance:
	            dataAvailable = reinterpret_cast<RUEPositioningGpsAcquisitionAssistanceReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataBadSatList:
	        	dataAvailable = reinterpret_cast<RBadSatListReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataNavigationModel:
	        	dataAvailable = reinterpret_cast<RUEPositioningGpsNavigationModelReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataReferenceTime:
	        	dataAvailable = reinterpret_cast<RUEPositioningGpsReferenceTimeReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataIonosphericModel:
	        	dataAvailable = reinterpret_cast<RUEPositioningGpsIonosphericModelReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataReferenceLocation:
	        	dataAvailable = reinterpret_cast<RReferenceLocationReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataAlmanac:
	        	dataAvailable = reinterpret_cast<RUEPositioningGpsAlmanacReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        case EAssistanceDataPositioningGpsUtcModel:
	        	dataAvailable = reinterpret_cast<RUEPositioningGpsUtcModelReader*>(&aDataRoot)->IsDataAvailable();
	            break;
	        default:
	            //Intentionally empty. dataAvailable remains EFalse.
	            break;
	        }
	        
		if (!dataAvailable)
			{
			error = KErrNotFound;
			}
		else
			{
			aTimeStamp = aDataRoot.TimeStamp();	
			}
		}
	return error;
	}

// request from integration module to read a particular  assistance data item time stamp only
TInt CNetworkGatewayHandler::GetAssistanceDataItemTimeStamp(TLbsAssistanceDataItem aItem, TTime& aTimeStamp)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::GetAssistanceDataItemTimeStamp()");
	TInt error = KErrNone;
	TTime timeStamp;
	
	switch(aItem)
    	{
        case EAssistanceDataAquisitionAssistance:
			{
			RUEPositioningGpsAcquisitionAssistanceReader reader;
			TRAP(error, reader.OpenL());
			if (KErrNone == error)
			    {
	            error = GetAssistanceDataItem(aItem, reader, timeStamp);
	            reader.Close();
			    }
			break;
			}
        case EAssistanceDataBadSatList:
			{
			RBadSatListReader reader;
			TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataNavigationModel:
			{
			RUEPositioningGpsNavigationModelReader reader;
			TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataReferenceTime:
			{
			RUEPositioningGpsReferenceTimeReader reader;
            TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataIonosphericModel:
			{
			RUEPositioningGpsIonosphericModelReader reader;
            TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataReferenceLocation:
			{
			RReferenceLocationReader reader;
            TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataAlmanac:
			{
			RUEPositioningGpsAlmanacReader reader;
            TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        case EAssistanceDataPositioningGpsUtcModel:
			{
			RUEPositioningGpsUtcModelReader reader;
            TRAP(error, reader.OpenL());
            if (KErrNone == error)
                {
                error = GetAssistanceDataItem(aItem, reader, timeStamp);
                reader.Close();
                }
			break;
			}
        default:
			{
			error = KErrNotFound;
			break;
			}
        }
        
    if (KErrNone == error)
    	{
    	aTimeStamp = timeStamp;
    	}

	return error;
	}


// request from integration module to request a new set of assistance data from network
void CNetworkGatewayHandler::SendAssistanceDataRequest(TLbsAsistanceDataGroup aDataItemMask)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::SendAssistanceDataRequest()");
 	TLbsNetAssistanceDataRequestMsg msg(aDataItemMask);
 	SendOrQueueMessage(msg);
 	}
	
void CNetworkGatewayHandler::SendSelfLocationRequest(const TLbsNetSessionIdInt& aSessionId, 
													 const TLbsNetPosRequestOptionsAssistanceInt& aOptions)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::SendSelfLocationRequest()");
 	TLbsNetSelfLocationRequestMsg msg(aSessionId, aOptions);
 	SendOrQueueMessage(msg);
	}
	
void CNetworkGatewayHandler::SendSelfLocationCancel(const TLbsNetSessionIdInt& aSessionId, TInt aReason)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::SendSelfLocationCancel()");
 	TLbsNetSelfLocationCancelMsg msg(aSessionId, aReason);
 	SendOrQueueMessage(msg);
	}

void CNetworkGatewayHandler::SendSystemStatusAdvice(TBool aTracking)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::SendSystemStatusAdvice()");
 	TLbsNetSystemStatusAdviceMsg msg(aTracking);
 	SendOrQueueMessage(msg);
	}
	
void CNetworkGatewayHandler::RunL()
	{
	LBSLOG2(ELogP1, "CNetworkGatewayHandler::RunL() Begin. Status: %d\n", iStatus.Int());
	__ASSERT_DEBUG(iStatus.Int() == KErrNone, User::Panic(KLbsAGPSManFault, iStatus.Int()));
	
	// Check if more queued messages await sending
	if (!iQ.IsEmpty())
		{
 		iNGChannel.SendMessage(iQ.Read(), iStatus);
 		SetActive();
		}
	LBSLOG(ELogP1, "CNetworkGatewayHandler::RunL() End\n");
	}
	
void CNetworkGatewayHandler::DoCancel()
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::DoCancel()");
	iNGChannel.CancelSendMessageNotification();
	}
	
TInt CNetworkGatewayHandler::RunError(TInt aError)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::RunError()\n");
	LBSLOG_ERR2(ELogP2, " %d \n", aError);
 	return aError;
	}

void CNetworkGatewayHandler::SendOrQueueMessage(TLbsNetInternalMsgBase& aMsg)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::SendOrQueueMessage()\n");
	if (!IsActive())
		{
 		iNGChannel.SendMessage(aMsg, iStatus);
 		SetActive();
		}
	else
		{
		QueueMessage(aMsg);
		}
	}
/**
Queues messages.
Performs implicit cancels if the queue not empty.
Supports only one self location session at a time.
*/	
void CNetworkGatewayHandler::QueueMessage(TLbsNetInternalMsgBase& aMsg)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::QueueMessage()\n");
	TBool removed;
	
	switch (aMsg.Type())
		{
		case TLbsNetInternalMsgBase::ESelfLocationRequest:
			// A new request implicitly cancels a previous request and/or cancel
			iQ.FindAndRemove(TLbsNetInternalMsgBase::ESelfLocationRequest);
			iQ.FindAndRemove(TLbsNetInternalMsgBase::ESelfLocationCancel);
			iQ.Write(aMsg);
			break;
			
		case TLbsNetInternalMsgBase::ESelfLocationCancel:
			// The AGPS manager should not send a Cancel twice
			removed = iQ.FindAndRemove(TLbsNetInternalMsgBase::ESelfLocationCancel);
			__ASSERT_DEBUG(removed == EFalse, User::Panic(KLbsAGPSManFault, KErrAlreadyExists));
			removed = removed == removed; //dummy for UREL
			iQ.Write(aMsg);
			break;
			
		case TLbsNetInternalMsgBase::EAssistanceDataRequest:
			// It is an implicit cancel of a previous Assistance Data Request
			iQ.FindAndRemove(TLbsNetInternalMsgBase::EAssistanceDataRequest);
			iQ.Write(aMsg);
			break;
			
		case TLbsNetInternalMsgBase::ESystemStatusAdvice:
			// It is an implicit cancel of a previous System Status Advice
			iQ.FindAndRemove(TLbsNetInternalMsgBase::ESystemStatusAdvice);
			iQ.Write(aMsg);
			break;
			
		default:
			break;
			
		}
	}

//---------------------------------------------------------------------------------------------------
void CNetworkGatewayHandler::ProcessNetChannelMessage(RLbsNetChannel::TLbsNetChannelId aChannelId, 
													  const TLbsNetInternalMsgBase& aMessage)
	{
	LBSLOG(ELogP1, "CNetworkGatewayHandler::ProcessNetChannelMessage()\n");
	__ASSERT_DEBUG(aChannelId == RLbsNetChannel::EChannelAGPS2NG, User::Panic(KLbsAGPSManFault, EAGPSManUnexpectedNetChannelId));
	(void) aChannelId;
		
	const TLbsNetSessionCompleteAgpsMsg& msgComp = static_cast<const TLbsNetSessionCompleteAgpsMsg&>(aMessage);
	const TLbsNetAssistanceDataResponseMsg& msgAss = static_cast<const TLbsNetAssistanceDataResponseMsg&>(aMessage);

	switch (aMessage.Type())
		{
		case TLbsNetInternalMsgBase::ESessionComplete:
			iObserver->OnSessionComplete(msgComp.Reason(), msgComp.SessionId());
			break;
			
		case TLbsNetInternalMsgBase::EAssistanceDataResponse:
			iObserver->OnAssistanceDataResponse(msgAss.Reason(), msgAss.DataResponseMask());
			break;
			
		default:
			LBSLOG_ERR2(ELogP2, "Unexpected message type: %d \n", aMessage.Type());
			__ASSERT_DEBUG(EFalse, User::Panic(KLbsAGPSManFault, KErrArgument));
			break;
		}
	}