locationmgmt/networkgateway/src/agpschannel.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationmgmt/networkgateway/src/agpschannel.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,410 @@
+// 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:
+// Definition of assistance data channel component.
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#include <e32base.h>
+#include <e32property.h>
+#include <lbs/lbsassistancedatabase.h>
+#include <lbs/lbsassistancedatabuilderset.h>
+
+#include <lbs/lbslocerrors.h>
+#include <lbserrors.h>
+#include "lbsassistancedatacacheapi.h"
+#include "agpschannel.h"
+#include "lbsdevloggermacros.h"
+#include "lbsnrhngmsgs.h"
+const TLbsNetSessionIdInt KDummySessionId(TUid::Uid(0xDEADBEEF), 0xDEADBEEF);
+
+//
+// CAgpsChannel
+//
+
+CAgpsChannel::CAgpsChannel(MAgpsObserver& aObserver) : 
+	CActive(EPriorityStandard),
+	iSessionCompleteMsgBuffer(KDummySessionId, KErrNotFound),
+	iSessionCompleteMsgValid(EFalse),
+	iObserver(aObserver)
+	{
+	}
+	
+CAgpsChannel::~CAgpsChannel()
+	{
+	Cancel();
+	iAssistanceDataMsgBuffer.Close();
+	iAssistanceDataCache.Close();
+	iAGPSChannel.Close();
+	}
+
+CAgpsChannel* CAgpsChannel::NewL(MAgpsObserver& aObserver)
+	{
+	CAgpsChannel* self = new (ELeave) CAgpsChannel(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+		
+void CAgpsChannel::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	iAssistanceDataMsgBuffer.OpenL();
+	iAssistanceDataCache.OpenL();
+	iAGPSChannel.OpenL(RLbsNetChannel::EChannelNG2AGPS, *this);
+	}
+	
+void CAgpsChannel::RunL()
+	{
+	LBSLOG(ELogP1, "CAgpsChannel::RunL():");
+	__ASSERT_DEBUG(iStatus.Int() == KErrNone, User::Panic(KLbsNRHFault, iStatus.Int()));
+
+	// Session Complete has higher priority
+	if (iSessionCompleteMsgValid)
+		{
+		iAGPSChannel.SendMessage(iSessionCompleteMsgBuffer, iStatus);
+		iSessionCompleteMsgValid = EFalse;
+		SetActive();
+		}
+	else if (!iAssistanceDataMsgBuffer.IsEmpty())
+		{
+		TLbsNetAssistanceDataResponseMsg msg(0,0); //Empty msg
+		iAssistanceDataMsgBuffer.Read(msg);
+		iAGPSChannel.SendMessage(msg, iStatus);
+		SetActive();
+		}
+	}
+	
+void CAgpsChannel::DoCancel()
+	{
+	iAGPSChannel.CancelSendMessageNotification();
+	}
+	
+TInt CAgpsChannel::RunError(TInt aError)
+	{
+	return aError;
+	}
+
+void CAgpsChannel::SendAssistanceDataResponse(TInt aError, 
+											  TLbsAsistanceDataGroupInt aMask, 
+											  const RLbsAssistanceDataBuilderSet& aData)
+	{
+	LBSLOG(ELogP1, "CAgpsChannel::SendAssistanceDataResponse() CAgpsChannel::SendAssistanceDataResponse:");
+	TInt err = KErrNone;
+	if (aError == KErrNone)
+		{
+		TRAP(err, SetAssistanceDataCacheL(aData));
+		__ASSERT_DEBUG(err == KErrNone, User::Panic(KLbsNRHFault, err));
+		}
+	else if(aError == KPositionAssistanceDataReset)
+		{
+		err = iAssistanceDataCache.ResetAssistanceData(aMask);
+		__ASSERT_DEBUG(err == KErrNone, User::Panic(KLbsNRHFault, err));
+		}
+	
+	// Do not send if writing the cache failed
+	if (err == KErrNone)
+		{
+		TLbsNetAssistanceDataResponseMsg msg(aMask, aError);
+		if (!IsActive())
+			{
+			LBSLOG(ELogP2, "CAgpsChannel::SendAssistanceDataResponse() iAGPSChannel.SendMessage()");
+			iAGPSChannel.SendMessage(msg, iStatus);
+			SetActive();
+			}
+		else
+			{
+			LBSLOG(ELogP2, "CAgpsChannel::SendAssistanceDataResponse() iAssistanceDataMsgBuffer.Write()");
+			iAssistanceDataMsgBuffer.Write(msg);
+			}
+		}
+	}
+	
+void CAgpsChannel::SendSessionComplete(TInt aReason, const TLbsNetSessionIdInt& aSessionId)
+	{
+	TLbsNetSessionCompleteAgpsMsg msg(aSessionId, aReason);
+	if (!IsActive())
+		{
+		iAGPSChannel.SendMessage(msg, iStatus);
+		SetActive();
+		}
+	else
+		{
+		iSessionCompleteMsgBuffer = msg;
+		iSessionCompleteMsgValid = ETrue;
+		}
+	}
+	
+
+void CAgpsChannel::SetAssistanceDataCacheL(const RLbsAssistanceDataBuilderSet& aData)
+	{
+	RUEPositioningGpsAlmanacBuilder* almanacPtr;
+	RUEPositioningGpsIonosphericModelBuilder* ionosphericPtr;
+	RUEPositioningGpsNavigationModelBuilder* navigationPtr;
+	RUEPositioningGpsReferenceTimeBuilder* referenceTimePtr;
+	RUEPositioningGpsUtcModelBuilder*  utcPtr;
+	RUEPositioningGpsAcquisitionAssistanceBuilder* acquisitionPtr;
+	RBadSatListBuilder* badSatPtr;
+	RReferenceLocationBuilder* referenceLocationPtr;
+
+	RLbsAssistanceDataBuilderSet& data = const_cast<RLbsAssistanceDataBuilderSet&>(aData);
+	
+	// Check each item in turn and publish if it is valid
+	// Publish the latest assistance data into the relevant properties
+	if (KErrNone == data.GetDataBuilder(almanacPtr))
+		{
+		if (almanacPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataAlmanac, 
+									   *almanacPtr));
+			}
+		}
+	
+	if (KErrNone == data.GetDataBuilder(acquisitionPtr))
+		{
+		if (acquisitionPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataAquisitionAssistance, 
+									   *acquisitionPtr));
+			}
+		}
+		
+	if (KErrNone == data.GetDataBuilder(badSatPtr))
+		{
+		if (badSatPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataBadSatList, 
+									   *badSatPtr));
+			}
+		}
+		
+	if (KErrNone == data.GetDataBuilder(navigationPtr))
+		{
+		if (navigationPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataNavigationModel, 
+									   *navigationPtr));
+			}
+		}
+
+	if (KErrNone == data.GetDataBuilder(referenceTimePtr))
+		{
+		if (referenceTimePtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataReferenceTime, 
+									   *referenceTimePtr));
+			}
+		}
+
+	if (KErrNone == data.GetDataBuilder(ionosphericPtr))
+		{
+		if (ionosphericPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataIonosphericModel, 
+									   *ionosphericPtr));
+			}
+		}
+
+	if (KErrNone == data.GetDataBuilder(referenceLocationPtr))
+		{
+		if (referenceLocationPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataReferenceLocation, 
+									   *referenceLocationPtr));
+			}
+		}
+
+	if (KErrNone == data.GetDataBuilder(utcPtr))
+		{
+		if (utcPtr->IsDataAvailable())
+			{
+			User::LeaveIfError(iAssistanceDataCache.SetAssistDataItem(EAssistanceDataPositioningGpsUtcModel, 
+									   *utcPtr));
+			}
+		}
+	}
+	
+void CAgpsChannel::ProcessNetChannelMessage(RLbsNetChannel::TLbsNetChannelId aChannelId, const TLbsNetInternalMsgBase& aMessage)
+	{
+	__ASSERT_DEBUG(aChannelId == RLbsNetChannel::EChannelNG2AGPS, User::Panic(KLbsNGFault, ENGUnexpectedNetChannelId));
+	(void) aChannelId;
+	
+	const TLbsNetAssistanceDataRequestMsg& msgAssReq    = static_cast<const TLbsNetAssistanceDataRequestMsg&>(aMessage);
+	const TLbsNetSelfLocationRequestMsg&   msgLocReq    = static_cast<const TLbsNetSelfLocationRequestMsg&>(aMessage);
+	const TLbsNetSelfLocationCancelMsg&    msgLocCancel = static_cast<const TLbsNetSelfLocationCancelMsg&>(aMessage);
+	const TLbsNetSystemStatusAdviceMsg&	   msgSysStat   = static_cast<const TLbsNetSystemStatusAdviceMsg&>(aMessage);
+												
+	switch (aMessage.Type())
+		{
+		case TLbsNetInternalMsgBase::EAssistanceDataRequest:
+			iObserver.OnAssistanceDataRequest(msgAssReq.DataRequestMask());
+			break;
+			
+		case TLbsNetInternalMsgBase::ESelfLocationRequest:
+			iObserver.OnSelfLocationRequest(msgLocReq.SessionId(), msgLocReq.Options());
+			break;
+			
+		case TLbsNetInternalMsgBase::ESelfLocationCancel:
+			iObserver.OnSelfLocationCancel(msgLocCancel.SessionId(), msgLocCancel.Reason());
+			break;
+			
+		case TLbsNetInternalMsgBase::ESystemStatusAdvice:
+			iObserver.OnSystemStatusAdvice(msgSysStat.Tracking());
+			break;
+			
+		default:
+			__ASSERT_DEBUG(EFalse, User::Panic(KLbsNGFault, ENGUnexpectedMsgType));
+			break;
+		}
+	}
+
+//
+// RAssistanceDataMsgBuffer
+//
+RAssistanceDataMsgBuffer::TBufferItem::TBufferItem():
+	iValid(EFalse),
+	iReason(KErrNone)
+	{
+	}
+	
+/**
+*/	
+RAssistanceDataMsgBuffer::RAssistanceDataMsgBuffer():
+	iBuffer(KAssistanceDataListCount),
+	iEmpty(ETrue),
+	iErrGeneric()
+	{
+	}
+	
+/**
+*/	
+void RAssistanceDataMsgBuffer::OpenL()
+	{
+	TBufferItem emptyItem;
+	
+	for (TInt i = 0; i < KAssistanceDataListCount; i++)
+		{
+		iBuffer.AppendL(emptyItem);
+		}
+	}
+/**
+*/
+void RAssistanceDataMsgBuffer::Close()
+	{
+	iBuffer.Close();
+	}
+/**
+*/	
+void RAssistanceDataMsgBuffer::Write(const TLbsNetAssistanceDataResponseMsg& aMsg)
+	{
+	LBSLOG(ELogP1, "RAssistanceDataMsgBuffer::Write():");
+	TInt reason = aMsg.Reason();
+	TLbsAsistanceDataGroup mask = aMsg.DataResponseMask();
+	__ASSERT_DEBUG((mask != 0) || (mask==0 && reason<0), User::Panic(KLbsNGFault, KErrArgument));
+	if (EAssistanceDataNone == mask)
+		{
+		// assume something error code comes in
+		iErrGeneric.iValid = ETrue;
+		iErrGeneric.iReason = reason;
+		}	
+	else
+		{
+		for (TInt i = 0; i < KAssistanceDataListCount; i++)
+			{
+			if (mask & 0x01 == 0x01)
+				{
+				iBuffer[i].iValid  = ETrue;
+				iBuffer[i].iReason = reason;
+				}
+			
+			mask = mask >> 1;
+			}
+		}
+	iEmpty = EFalse;
+	}
+	
+/**
+*/	
+void RAssistanceDataMsgBuffer::Read(TLbsNetAssistanceDataResponseMsg& aMsg)
+	{
+	LBSLOG(ELogP1, "RAssistanceDataMsgBuffer::Read()"); 
+	__ASSERT_DEBUG((iBuffer.Count() != 0), User::Panic(KLbsNGFault, KErrUnderflow));
+
+	TInt reason = KErrNone;
+	TInt valid = EFalse;
+	TInt mask = 0;
+	TInt i; //first loop
+	TInt j; //second loop
+	// Check error item
+	if (iErrGeneric.iValid)	
+		{
+		mask = 0;
+		reason = iErrGeneric.iReason;
+		iErrGeneric.iValid = EFalse;
+
+		iEmpty = ETrue;
+		for (i = 0; i < KAssistanceDataListCount; i++)
+			{
+			if (iBuffer[i].iValid) 
+				{
+				iEmpty = EFalse;
+				break;
+				}
+			}
+		}
+	else
+		{
+		// Find first valid item. Save the reason code
+		for (i = 0; i < KAssistanceDataListCount; i++)
+			{
+			if (iBuffer[i].iValid) 
+				{
+				reason = iBuffer[i].iReason;
+				break;
+				}
+			}
+
+		// Find other valid items with the same reason code
+		for (j = i; j < KAssistanceDataListCount; j++)
+			{
+			if (iBuffer[j].iValid && (iBuffer[j].iReason == reason))
+				{
+				mask = mask | (0x00000001 << j);
+				iBuffer[j].iValid = EFalse;
+				}
+			valid = valid || iBuffer[j].iValid;
+			}
+		iEmpty = !valid;
+		}
+	
+	LBSLOG2(ELogP2, "RAssistanceDataMsgBuffer::Read() iEmpty=%d", iEmpty);
+	LBSLOG2(ELogP2, "RAssistanceDataMsgBuffer::Read() mask=%d", mask);
+	LBSLOG2(ELogP2, "RAssistanceDataMsgBuffer::Read() reason=%d", reason);
+
+	TLbsNetAssistanceDataResponseMsg msg(mask, reason);
+	aMsg = msg;
+	}
+	
+/**
+*/	
+TBool RAssistanceDataMsgBuffer::IsEmpty() const
+	{
+	return iEmpty;
+	}