lbs/lbstestutils/src/tlbsutils.cpp
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lbs/lbstestutils/src/tlbsutils.cpp	Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,1318 @@
+// 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 the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// @file CT_Utils.cpp
+// This is the Cpp file which contains the utility functions common across the servers
+// 
+//
+
+// User includes
+#include "tlbsutils.h"
+#include "ctlbsconfigreader.h"
+#include "ctlbsasyncwaiter.h"
+#include "ctlbstestloggermacros.h"
+
+// Epoc includes
+#include <f32file.h>
+#include <e32math.h>
+#include <e32property.h>
+
+// Lbs includes
+#include <lbsclasstypes.h>
+#include <lbssatellite.h>
+
+
+// defines
+#define BAD_MODULE_ID	0x87654321
+
+
+/**
+*/
+EXPORT_C TLbsModuleUpdateItem::TLbsModuleUpdateItem()
+	{
+	}
+
+
+/**
+*/
+EXPORT_C const TPositionSatelliteInfo& TLbsModuleUpdateItem::Position() const
+	{
+	return iPosition;
+	}
+
+/**
+*/
+EXPORT_C void TLbsModuleUpdateItem::SetPosition(const TPositionSatelliteInfo& aPosition)
+	{
+	iPosition = aPosition;
+	}
+
+
+/**
+*/
+EXPORT_C const TPositionGpsMeasurementInfo& TLbsModuleUpdateItem::Measurement() const
+	{
+	return iMeasurement;
+	}
+
+/**
+*/
+EXPORT_C void TLbsModuleUpdateItem::SetMeasurement(const TPositionGpsMeasurementInfo& aMeasurement)
+	{
+	iMeasurement = aMeasurement;
+	}
+
+
+/**
+*/
+EXPORT_C TInt TLbsModuleUpdateItem::Error() const
+	{
+	return iError;
+	}
+
+/**
+*/
+EXPORT_C void TLbsModuleUpdateItem::SetDelay(TInt aDelay)
+	{
+	iDelay = aDelay;
+	}
+
+/**
+*/
+EXPORT_C TInt TLbsModuleUpdateItem::Delay() const
+	{
+	return iDelay;
+	}
+
+/**
+*/
+EXPORT_C void TLbsModuleUpdateItem::SetError(TInt aError)
+	{
+	iError = aError;
+	}
+
+
+
+EXPORT_C T_LbsUtils::T_LbsUtils()
+/** Constructor.
+*/
+	{
+	}
+
+
+EXPORT_C T_LbsUtils::~T_LbsUtils()
+/** Destructor.
+*/
+	{
+	}
+
+
+/*EXPORT_C static*/ /*void GetDefault_ModuleStatusInfo(TModuleConfiguredStatus& aStatusInfo)
+	{
+		(void)aStatusInfo;	
+	}
+*/
+
+
+EXPORT_C void T_LbsUtils::CreateTestPropertiesL()
+/** Creates the test properties for the test module. To allow data to be passed between
+	test steps and the test module.
+*/
+	{
+	const TSecurityPolicy KReadPolicy(ECapability_None);
+	const TSecurityPolicy KWritePolicy(ECapabilityWriteDeviceData);
+
+
+	// Create the test module data bus properties.
+	TInt err;
+	
+	// Data to the test module.
+	err = RProperty::Define(KUidSystemCategory, ELbsTestAGpsModuleIn, RProperty::ELargeByteArray, KReadPolicy, KWritePolicy, sizeof(TModuleDataIn));
+	if ((KErrNone != err) && (KErrAlreadyExists != err))
+	{
+		User::LeaveIfError(err);
+	}
+	
+	// Data from the test module.
+	err = RProperty::Define(KUidSystemCategory, ELbsTestAGpsModuleOut, RProperty::ELargeByteArray, KReadPolicy, KWritePolicy, sizeof(TModuleDataOut));
+	if ((KErrNone != err) && (KErrAlreadyExists != err))
+	{
+		User::LeaveIfError(err);
+	}
+
+	// Data from the test clock plugin.
+	err = RProperty::Define(KUidSystemCategory, ELbsTestClockPluginOut, RProperty::ELargeByteArray, KReadPolicy, KWritePolicy, sizeof(TClockPluginDataOut));
+	if ((KErrNone != err) && (KErrAlreadyExists != err))
+	{
+		User::LeaveIfError(err);
+	}
+	
+	// Creating the property for allowing the AGPS module to report when the mode it's running in changes
+	err = RProperty::Define(KUidSystemCategory, ELbsTestAGpsModuleModeChanges, RProperty::ELargeByteArray, KReadPolicy, KWritePolicy, sizeof(TLbsGpsOptionsArray));
+	if ((KErrNone != err) && (KErrAlreadyExists != err))
+		{
+			User::LeaveIfError(err);
+		}
+
+	// Create other test properties here also - just update the TLbsTestPropertyKeys enum don't add extra Categories.
+
+	}
+
+
+EXPORT_C void T_LbsUtils::GetConfigured_PosInfosL(const TDesC& aConfigFileName, const TDesC& aConfigSection, RPointerArray<TAny>& aPosInfoArr)
+/** Fills a position info array with values read from a configuration ini file.
+
+@param aConfigFileName	The name of the ini file to read. If the file name is empty (0 length) then
+						the array will contain a single pos info item with default values.
+@param aConfigSection	The section within the ini file to read data from.
+@param aPosInfoArr		The pos info array to which the items are added. The array will cleared of
+						existing items.
+*/
+	{
+	// Clear array.
+	ResetAndDestroy_PosInfoArr(aPosInfoArr);
+
+	// Check for config file, if not present create a single default TPositionInfo.
+	if (aConfigFileName.Length() == 0)
+		{
+		TPositionSatelliteInfo* posInfo = new(ELeave) TPositionSatelliteInfo();
+		TPosition position;
+
+		position.SetCoordinate(DEFAULT_NOTIFY_POS_UPDATE_LATITUDE, DEFAULT_NOTIFY_POS_UPDATE_LONGITUDE, DEFAULT_NOTIFY_POS_UPDATE_ALTITUDE);
+		position.SetAccuracy(DEFAULT_NOTIFY_POS_UPDATE_HORIZONTAL_ACCURACY, DEFAULT_NOTIFY_POS_UPDATE_VERTICAL_ACCURACY);
+		position.SetCurrentTime();
+	
+		posInfo->SetPosition(position);
+
+		User::LeaveIfError(aPosInfoArr.Append(posInfo));			
+		}
+	
+	else
+		{
+		CPosInfoConfigReader* reader;
+	
+		reader = CPosInfoConfigReader::NewL(aConfigFileName, aConfigSection, aPosInfoArr);
+		CleanupStack::PushL(reader);
+		
+		reader->ProcessL();
+	
+		CleanupStack::PopAndDestroy(reader);
+		}
+	}
+
+EXPORT_C void T_LbsUtils::GetConfigured_UpdateArrayL(const TDesC& aConfigFileName, const TDesC& aConfigSection, RPointerArray<TLbsModuleUpdateItem>& aUpdateArr)
+/** Fills an updata array structure with values read from a configuration ini file.
+
+@param aConfigFileName	The name of the ini file to read. If the file name is empty (0 length) then
+						default values will be used.
+@param aConfigSection	The section within the ini file to read data from.
+@param aUpdateArr		The update array to be populated.
+*/
+	{
+	// Use default values if file name not given.
+	if (aConfigFileName.Length() == 0)
+		{
+		// I am not sure we want to fill in the array with default values - ??
+		}
+	
+	else
+		{
+		CUpdateConfigReader* reader;
+	
+		reader = CUpdateConfigReader::NewL(aConfigFileName, aConfigSection, aUpdateArr);
+		CleanupStack::PushL(reader);
+		
+		reader->ProcessL();
+	
+		CleanupStack::PopAndDestroy(reader);
+		}
+	}
+
+
+// don't think we need this...
+EXPORT_C void T_LbsUtils::GetConfigured_ModuleStatusL(const TDesC& aConfigFileName, const TDesC& aConfigSection, TPositionModuleStatus& aModuleStatus)
+	{
+	// Use default values if file name not given.
+	if (aConfigFileName.Length() == 0)
+		{
+		aModuleStatus.SetDeviceStatus(TPositionModuleStatus::EDeviceReady);
+		aModuleStatus.SetDataQualityStatus(TPositionModuleStatus::EDataQualityNormal);
+		}
+	else
+		{
+		CModuleStatusConfigReader* reader;
+	
+		reader = CModuleStatusConfigReader::NewL(aConfigFileName, aConfigSection, aModuleStatus);
+		CleanupStack::PushL(reader);
+				
+		reader->ProcessL();
+	
+		CleanupStack::PopAndDestroy(reader);
+		}
+	}
+
+
+EXPORT_C void T_LbsUtils::GetConfigured_ModuleUpdateOptionsL(const TDesC& aConfigFileName, const TDesC& aConfigSection, TPositionUpdateOptions& aUpdateOpts)
+/** Fills a module updata options class/structure with values read from a configuration ini file.
+
+@param aConfigFileName	The name of the ini file to read. If the file name is empty (0 length) then
+						default values will be used.
+@param aConfigSection	The section within the ini file to read data from.
+@param aUpdateOpts		The modified update options structure.
+*/
+	{
+	// Use default values if file name not given.
+	if (aConfigFileName.Length() == 0)
+		{
+		aUpdateOpts.SetUpdateInterval(0);
+		aUpdateOpts.SetUpdateTimeOut(0);
+		aUpdateOpts.SetMaxUpdateAge(0);
+		aUpdateOpts.SetAcceptPartialUpdates(EFalse);			
+		}
+	
+	else
+		{
+		CUpdateOptsConfigReader* reader;
+	
+		reader = CUpdateOptsConfigReader::NewL(aConfigFileName, aConfigSection, aUpdateOpts);
+		CleanupStack::PushL(reader);
+		
+		reader->ProcessL();
+	
+		CleanupStack::PopAndDestroy(reader);
+		}
+	}
+
+EXPORT_C void T_LbsUtils::GetConfigured_ClientDetailsL(const TDesC& aConfigFileName, const TDesC& aConfigSection, 
+						RArray<TCTClientDetails>& aClientDetailsArray)
+/** Gets the delays for each client with values read from a configuration ini file.
+
+@param aConfigFileName		The name of the ini file to read. If the file name is empty (0 length) then
+							default values will be used.
+@param aConfigSection		The section within the ini file to read data from.
+@param aClientDelayArray	The array of client delays.
+*/
+	{
+	// Use default values if file name not given.
+	if (aConfigFileName.Length() == 0)
+		{ // by default have one client
+		TCTClientDetails client;
+		aClientDetailsArray.AppendL(client);
+		return;
+		}
+	
+	else
+		{
+		CClientDetailsConfigReader* reader;
+		reader = CClientDetailsConfigReader::NewL(aConfigFileName, aConfigSection, aClientDetailsArray);
+		CleanupStack::PushL(reader);
+		
+		reader->ProcessL();
+	
+		CleanupStack::PopAndDestroy(reader);
+		if(aClientDetailsArray.Count() == 0)
+			{ // by default have one client
+			TCTClientDetails client;
+			aClientDetailsArray.AppendL(client);
+			}
+		}
+	}
+
+EXPORT_C void T_LbsUtils::GetExpected_ModuleModes(const TDesC& aConfigFileName, const TDesC& aConfigSection, RPointerArray<TLbsGpsOptions>& aModuleModes)
+	{
+	if (aConfigFileName.Length() == 0)
+		{
+		return;
+		}
+	
+	CAgpsModuleModesConfigReader* reader;
+	reader = CAgpsModuleModesConfigReader::NewL(aConfigFileName, aConfigSection, aModuleModes);
+	CleanupStack::PushL(reader);
+	reader->ProcessL();
+	CleanupStack::PopAndDestroy(reader);
+	}
+
+
+EXPORT_C void T_LbsUtils::NotifyModuleOfConfigChangeL(const TModuleDataIn& aModuleDataIn)
+/** Notify the module of a configuration change.
+
+Used when the test harness has read a configuration file and wishes to notify the test module
+that it should also do a read of the configuration file. To ensure both the test harness and
+the test module are using the same reference data.
+	
+The ELbsTestAGpsModuleIn property is used to pass the ini file and section names to the
+test module. The ELbsTestAGpsModuleOut is then used to receive an response from the test module.
+
+@param aConfigFileName	The file name string to send to the test mdoule.
+@param aConfigSection	The ini section name string to send to the test module.
+*/
+	{
+	// Ask to be notified when the module receives the ini file re-read request.
+
+	// Attach and subscribe to listen for data bus updates. Use the async waiter to process
+	// the update.
+	RProperty modDataOutProperty;
+	User::LeaveIfError(modDataOutProperty.Attach(KUidSystemCategory, ELbsTestAGpsModuleOut));
+
+	CT_LbsAsyncWaiter* waiter = CT_LbsAsyncWaiter::NewL();
+	CleanupStack::PushL(waiter);
+
+	modDataOutProperty.Subscribe(waiter->iStatus);
+
+
+	// Publish the file and section names to the module, to inform the module it has to
+	// carry out a re-read of the ini file.
+	TPckgBuf<TModuleDataIn> modDataInBuf;
+	TModuleDataIn& modDataIn = modDataInBuf();
+
+	// Copy across all the data items.
+	modDataIn.iRequestType = aModuleDataIn.iRequestType;
+	modDataIn.iConfigFileName = aModuleDataIn.iConfigFileName;
+	modDataIn.iConfigSection = aModuleDataIn.iConfigSection;
+	modDataIn.iAssDataEventType = aModuleDataIn.iAssDataEventType;
+	modDataIn.iAssDataTestMode = aModuleDataIn.iAssDataTestMode;
+	modDataIn.iKickOffEventType = aModuleDataIn.iKickOffEventType;
+	modDataIn.iTimeOut = aModuleDataIn.iTimeOut;
+	modDataIn.iError = aModuleDataIn.iError;
+	modDataIn.iTimeStampOffset = aModuleDataIn.iTimeStampOffset;
+    modDataIn.iOptionsChangeReportMode = aModuleDataIn.iOptionsChangeReportMode;
+
+	User::LeaveIfError(RProperty::Set(KUidSystemCategory, ELbsTestAGpsModuleIn, modDataInBuf));
+
+	TBool noResponse = ETrue;
+
+	// Wait for the notification from the test module.	
+	while(noResponse)
+		{
+	waiter->StartAndWait();
+	User::LeaveIfError(waiter->Result());
+
+	// Now ensure the notification response was good.
+	TModuleDataOut modDataOut;
+	TPckg<TModuleDataOut> modDataOutPckg(modDataOut);
+
+	User::LeaveIfError(modDataOutProperty.Get(modDataOutPckg));
+
+		if ((TModuleDataOut::EModuleResponse == modDataOut.iRequestType) && (TModuleDataOut::EModuleResponseOk == modDataOut.iResponse)) 
+		{
+			noResponse = EFalse;
+			}
+		}
+
+	CleanupStack::PopAndDestroy(waiter);
+	}
+
+
+EXPORT_C void T_LbsUtils::WaitForModuleToRequestAssistanceDataL()
+/** Wait for notification that the test AGPS module as requested assistance data.
+
+	Blocking function used to determine when the test module has requested assistance data as part of its location update.
+*/
+	{
+	RProperty modDataOutProperty;
+	User::LeaveIfError(modDataOutProperty.Attach(KUidSystemCategory, ELbsTestAGpsModuleOut));
+
+	CT_LbsAsyncWaiter* waiter = CT_LbsAsyncWaiter::NewL();
+	CleanupStack::PushL(waiter);
+
+	modDataOutProperty.Subscribe(waiter->iStatus);
+
+	// Wait for the notification from the test module.	
+	waiter->StartAndWait();
+	User::LeaveIfError(waiter->Result());
+
+	// Ensure the correct response is given.
+	TModuleDataOut modDataOut;
+	TPckg<TModuleDataOut> modDataOutPckg(modDataOut);
+
+	User::LeaveIfError(modDataOutProperty.Get(modDataOutPckg));
+	
+	if (TModuleDataOut::EModuleAssDataRequestedOk != modDataOut.iResponse)
+		{
+		User::LeaveIfError(KErrArgument);
+		}
+
+	CleanupStack::PopAndDestroy(waiter);
+	}
+
+EXPORT_C TBool T_LbsUtils::Compare_PosInfo(const TPositionInfoBase& aPosInfoSideA, const TPositionInfoBase& aPosInfoSideB)
+/** Compare two position info structures. Ensure all fields match excatly.
+
+@param aPosInfoSideA	The first structure to compare.
+@param aPosInfoSideB	The second structure to compare.
+@return					ETrue if both structure match excatly else EFalse.
+*/
+	{
+	return Compare_PosInfo(aPosInfoSideA, aPosInfoSideB, EExactAccuracy);
+	}
+
+
+EXPORT_C TBool T_LbsUtils::Compare_PosInfo(const TPositionInfoBase& aPosInfoSideA, const TPositionInfoBase& aPosInfoSideB, TComparisonAccuracyType aCmpAccuracy)
+	{
+	// TODO compare base class items, such as module id, position mode, etc.
+
+	TUint32 typeA = aPosInfoSideA.PositionClassType();
+	TUint32 typeB = aPosInfoSideB.PositionClassType();
+	
+	// Compare TPositionInfo type items.
+	if(typeA & typeB & EPositionInfoClass)
+		{
+		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionInfoClass");
+		const TPositionInfo& posInfoSideA = reinterpret_cast<const TPositionInfo&>(aPosInfoSideA);
+		const TPositionInfo& posInfoSideB = reinterpret_cast<const TPositionInfo&>(aPosInfoSideB);
+		
+		TPosition posSideA;
+		TPosition posSideB;
+		posInfoSideA.GetPosition(posSideA);
+		posInfoSideB.GetPosition(posSideB);
+
+		// Carry out an exact check when comparing items.
+		if (EExactAccuracy == aCmpAccuracy)
+			{
+			TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Comparing positions for exact match");
+			// Compare latitude. 
+			if (Math::IsNaN(posSideA.Latitude()) && Math::IsNaN(posSideB.Latitude()))
+				;
+			else if (posSideA.Latitude() != posSideB.Latitude())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Latitudes %d and %d respectively", posSideA.Latitude(), posSideB.Latitude());
+				return EFalse;
+				}
+			
+			// Compare longitude.
+			if (Math::IsNaN(posSideA.Longitude()) && Math::IsNaN(posSideB.Longitude()))
+				;
+			else if (posSideA.Longitude() != posSideB.Longitude())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Longitudes %d and %d respectively", posSideA.Longitude(), posSideB.Longitude());
+				return EFalse;
+				}		
+			
+			// Compare altitude.
+			if (Math::IsNaN(posSideA.Altitude()) && Math::IsNaN(posSideB.Altitude()))
+				;
+			else if (posSideA.Altitude() != posSideB.Altitude())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Altitudes %d and %d respectively", posSideA.Altitude(), posSideB.Altitude());				
+				return EFalse;
+				}
+			
+			// Compare datum.
+			if (posSideA.Datum() != posSideB.Datum())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Datums %d and %d respectively", posSideA.Datum(), posSideB.Datum());				
+				return EFalse;
+				}				
+			
+			// Compare horizontal accuracy.
+			if (Math::IsNaN(posSideA.HorizontalAccuracy()) && Math::IsNaN(posSideB.HorizontalAccuracy()))
+				;
+			else if (posSideA.HorizontalAccuracy() != posSideB.HorizontalAccuracy())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Horizontal Accuracies %d and %d respectively", posSideA.HorizontalAccuracy(), posSideB.HorizontalAccuracy());				
+				return EFalse;
+				}		
+			
+			// Compare vertical accuracy.
+			if (Math::IsNaN(posSideA.VerticalAccuracy()) && Math::IsNaN(posSideB.VerticalAccuracy()))
+				;
+			else if (posSideA.VerticalAccuracy() != posSideB.VerticalAccuracy())
+				{
+				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
+				TESTLOG3(ELogP1, "Vertical Accuracies %d and %d respectively", posSideA.VerticalAccuracy(), posSideB.VerticalAccuracy());				
+				return EFalse;
+				}		
+			}
+		else
+			{
+			// Check latitude + longitude using horz accuracy.
+			TReal horzAct = posSideA.HorizontalAccuracy(); // Use the verify accuracy value (which is side A).
+			TReal distance ;			
+	
+			TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Comparing positions for 'rough' match");			
+		//	if(NAN != horzAct)
+				{
+				// The following is a temporary patch until TPositionInfo.Distance() is implemented:				
+/* 
+	from http://www.movable-type.co.uk/scripts/GIS-FAQ-5.1.html
+	
+	presuming a spherical Earth with radius R (see below), and the locations of the two points in spherical coordinates (longitude and latitude) are lon1,lat1 and lon2,lat2 then the
+
+	Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159):
+
+	dlon = lon2 - lon1
+	dlat = lat2 - lat1
+	a = sin^2(dlat/2) + cos(lat1) * cos(lat2) * sin^2(dlon/2)
+	c = 2 * arcsin(min(1,sqrt(a)))
+	d = R * c
+
+	will give mathematically and computationally exact results. 
+	
+*/				
+				const TReal pi = 3.141592653589793;
+				const TReal earthRadius = 6367 * 1000;	// earth radius in metres
+				
+				TReal32 latA = posSideA.Latitude() * (pi/180);
+				TReal32 latB = posSideB.Latitude() * (pi/180);
+				TReal32 lonA = posSideA.Longitude() * (pi/180);
+				TReal32 lonB = posSideB.Longitude() * (pi/180);
+				
+				TReal dlon = (lonB - lonA);	
+				TReal dlat = (latB - latA);
+				TReal sin_half_dlat, sin_half_dlon, coslatA, coslatB;
+				
+				Math::Sin(sin_half_dlat, dlat/2);
+				Math::Sin(sin_half_dlon, dlon/2);
+				Math::Cos(coslatA, latA);
+				Math::Cos(coslatB, latB);
+				
+				TReal a = (sin_half_dlat * sin_half_dlat) + (coslatA * coslatB * (sin_half_dlon * sin_half_dlon));
+				TReal sqrt_a;
+				Math::Sqrt(sqrt_a, a);
+				TReal arcsinmin;
+				
+				TReal min = Min(static_cast<TReal>(1), sqrt_a);
+				Math::ASin(arcsinmin, min);
+				
+				distance = earthRadius * (2 * arcsinmin);
+				
+				//__ASSERT_ALWAYS(!Math::IsNaN(distance), User::Panic(_L("Lbs Test Utils"), KErrGeneral));
+				if(Math::IsNaN(latA) || Math::IsNaN(lonA) || Math::IsNaN(horzAct))
+					{	
+					TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match because contains NaNs!");	
+					return EFalse;			
+					}
+				else if(distance > horzAct + 30)	// lrm allow for 30m discrepency for now TO DO figure out whether we should be able to check finer accuracy
+					{
+					TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match because distance greater than reported accuracy + margin!");
+					return EFalse;
+					}
+				}
+				
+			/*	put back later:	
+			TReal32 horzAct = posSideA.HorizontalAccuracy(); // Use the verify accuracy value (which is side A).
+			TReal32 distance ;			
+			
+			posSideA.Distance(posSideB, distance);
+			if (distance > horzAct)
+				return EFalse;
+		
+			// Check altitude using vert accuracy.
+			TReal32 vertAct = posSideA.VerticalAccuracy(); // Use the verify accuracy value (which is side A).
+			TReal32 height = Abs(posSideA.Altitude() - posSideB.Altitude());
+			if (height > vertAct)
+				return EFalse;
+			*/
+			
+			}
+			
+		// TODO, we don't compare times, not sure if this is something we would do later on
+//		if (posSideA.Time() != posSideB.Time())
+//			return EFalse;
+		
+		return ETrue;
+		}
+
+	// Compare TPositionCourseInfo type items.		
+	if (typeA & typeB & EPositionCourseInfoClass)
+		{
+		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionCourseInfoClass");
+		// TODO
+		}
+
+	// Compare TPositionSatelliteInfo type items.
+	if (typeA & typeB & EPositionSatelliteInfoClass)
+		{
+		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionSatelliteInfoClass");
+		// TODO
+		}
+
+/* For extended tests when we have them.
+	if (infoBase.PositionClassType() & EPositionClassTestExtension)
+		{
+		}
+*/
+	return EFalse;
+	}
+	
+	
+EXPORT_C TBool T_LbsUtils::Compare_PosInfoArr(RPointerArray<TAny>& aPosInfoArrSideA, RPointerArray<TAny>& aPosInfoArrSideB)
+	{
+	return Compare_PosInfoArr(aPosInfoArrSideA, aPosInfoArrSideB, EExactAccuracy);
+	}
+
+EXPORT_C TBool T_LbsUtils::Compare_PosInfoArr(RPointerArray<TAny>& aPosInfoArrSideA, RPointerArray<TAny>& aPosInfoArrSideB, TComparisonAccuracyType aCmpAccuracy)
+	{
+	// Only compare items if the arrays are the same size.
+	if (aPosInfoArrSideA.Count() == aPosInfoArrSideB.Count())
+		{
+		TPositionInfoBase* posInfoA;
+		TPositionInfoBase* posInfoB;
+		TBool res;
+		
+		for (TInt i = 0; i < aPosInfoArrSideA.Count(); ++i)
+			{
+			posInfoA = reinterpret_cast<TPositionInfoBase*>(aPosInfoArrSideA[i]);
+			posInfoB = reinterpret_cast<TPositionInfoBase*>(aPosInfoArrSideB[i]);
+			
+			res = Compare_PosInfo(*posInfoA, *posInfoB, aCmpAccuracy);
+			if (!res)
+				return EFalse;
+			}
+		}
+	
+	else
+		{
+		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfoArr() Failed because different number of positions in arrays being compared!");
+		return EFalse;
+		}
+	return ETrue;
+	}
+
+
+EXPORT_C void T_LbsUtils::ResetAndDestroy_PosInfoArr(RPointerArray<TAny>& aPosInfoArr)
+	{
+		for (TInt i = 0; i < aPosInfoArr.Count(); ++i)
+			delete aPosInfoArr[i];
+		aPosInfoArr.Reset();	
+	}
+
+
+EXPORT_C TPositionModuleId T_LbsUtils::GetNetworkModuleIdL(RPositionServer& aServer)
+	{
+	TPositionModuleId modId;
+
+	User::LeaveIfError(GetModIdByTechnology(aServer, TPositionModuleInfo::ETechnologyNetwork, modId));
+	
+	return modId;
+	}
+
+
+EXPORT_C TPositionModuleId T_LbsUtils::GetAGpsModuleIdL(RPositionServer& aServer)
+	{
+	TPositionModuleId modId;
+
+	User::LeaveIfError(GetModIdByTechnology(aServer, (TPositionModuleInfo::ETechnologyTerminal | TPositionModuleInfo::ETechnologyAssisted), modId));
+	
+	return modId;
+	}
+	
+EXPORT_C TPositionModuleId T_LbsUtils::GetBadModuleId()
+	{
+	TPositionModuleId modId;
+	
+	modId.iUid = BAD_MODULE_ID;
+		
+	return modId;
+	}	
+
+
+EXPORT_C TBool T_LbsUtils::Compare_ModuleInfo(TPositionModuleInfo& aModInfoSideA, TPositionModuleInfo& aModInfoSideB)
+	{
+	// Compare all module information items and quality.
+	
+	// Compare module id.
+	if (aModInfoSideA.ModuleId() != aModInfoSideB.ModuleId())
+		{
+		return EFalse;
+		}	
+
+	//	Compare is available flag.
+	if (aModInfoSideA.IsAvailable() != aModInfoSideB.IsAvailable())
+		{
+		return EFalse;
+		}	
+
+	// Compare technology type.
+	if (aModInfoSideA.TechnologyType() != aModInfoSideB.TechnologyType())
+		{
+		return EFalse;
+		}	
+
+	//	Compare device location.
+	if (aModInfoSideA.DeviceLocation() != aModInfoSideB.DeviceLocation())
+		{
+		return EFalse;
+		}	
+
+	//	Compare capabilities.
+	if (aModInfoSideA.Capabilities() != aModInfoSideB.Capabilities())
+		{
+		return EFalse;
+		}	
+
+	// Compare each of the family classes. Use min and max enum values.
+	for (TInt i = EPositionInfoFamily; i <= EPositionUpdateOptionsFamily; i++)
+		{
+		if (aModInfoSideA.ClassesSupported(static_cast<TPositionClassFamily>(i)) != aModInfoSideB.ClassesSupported(static_cast<TPositionClassFamily>(i)))
+			{
+			return EFalse;
+			}	
+		}
+		
+	// Compare version.
+	if ((aModInfoSideA.Version().iMajor != aModInfoSideB.Version().iMajor) ||
+		(aModInfoSideA.Version().iMinor != aModInfoSideB.Version().iMinor) ||
+		(aModInfoSideA.Version().iBuild != aModInfoSideB.Version().iBuild))
+		{
+		return EFalse;
+		}	
+
+	// Compare module name.
+	TBuf<KPositionMaxModuleName> modNameSideA;
+	TBuf<KPositionMaxModuleName> modNameSideB;
+
+	aModInfoSideA.GetModuleName(modNameSideA);
+	aModInfoSideB.GetModuleName(modNameSideB);
+	if (0 != modNameSideA.Compare(modNameSideB))
+	{
+		return EFalse;
+	}
+
+	// Compare module quality.
+	TPositionQuality qualitySideA;
+	TPositionQuality qualitySideB;	
+	
+	aModInfoSideA.GetPositionQuality(qualitySideA);
+	aModInfoSideB.GetPositionQuality(qualitySideB);
+	
+	return Compare_PositionQuality(qualitySideA, qualitySideB);
+	}
+
+EXPORT_C TBool T_LbsUtils::Compare_ModuleStatus(TPositionModuleStatus& aModStatusSideA, TPositionModuleStatus& aModStatusSideB)
+	{
+	// Compare device status.
+	if (aModStatusSideA.DeviceStatus() != aModStatusSideB.DeviceStatus())
+		{
+		return EFalse;
+		}	
+
+	//	Compare quality status.
+	if (aModStatusSideA.DataQualityStatus() != aModStatusSideB.DataQualityStatus())
+		{
+		return EFalse;
+		}	
+		
+	return TRUE;
+	}
+	
+	
+EXPORT_C TBool Compare_ModuleUpdateOptions(TPositionUpdateOptions& aModUpdateOptsSideA, TPositionUpdateOptions& aModUpdateOptsSideB)
+	{
+	// Compare base class items.
+	if(aModUpdateOptsSideA.PositionClassSize() != aModUpdateOptsSideB.PositionClassSize())
+		{
+			return EFalse;
+		}
+
+	if(aModUpdateOptsSideA.PositionClassType() != aModUpdateOptsSideB.PositionClassType())
+		{
+			return EFalse;
+		}
+	
+	// Compare interval option.
+	if(aModUpdateOptsSideA.UpdateInterval() != aModUpdateOptsSideB.UpdateInterval())
+		{
+			return EFalse;
+		}
+	
+	// Compare timeout option.
+	if(aModUpdateOptsSideA.UpdateTimeOut() != aModUpdateOptsSideB.UpdateTimeOut())
+		{
+			return EFalse;
+		}
+
+	// Compare maxage option.
+	if(aModUpdateOptsSideA.MaxUpdateAge() != aModUpdateOptsSideB.MaxUpdateAge())
+		{
+			return EFalse;
+		}
+
+	// Compare partial update option.
+	if(aModUpdateOptsSideA.AcceptPartialUpdates() != aModUpdateOptsSideB.AcceptPartialUpdates()) 
+		{
+			return EFalse;
+		}
+		
+	return ETrue;
+	}
+
+
+EXPORT_C TBool T_LbsUtils::Compare_PositionQuality(TPositionQuality& aQualitySideA, TPositionQuality& aQualitySideB)
+/** Compare two position quality structures.
+
+@param aQualitySideA	
+@param aQualitySideB	
+*/
+	{
+	// Check if each quality contains the same number of assigned quality items.
+	if (aQualitySideA.HighWaterMark() != aQualitySideB.HighWaterMark())
+	{
+		return EFalse;
+	}
+	
+	// Compare each quality item.
+	TInt endId = aQualitySideA.HighWaterMark();
+	
+	for (TInt i = 0; i <= endId; i++)
+		{
+		// Element for each side must be defined.
+		if (!aQualitySideA.IsDefined(i) || !aQualitySideB.IsDefined(i))
+			{
+			return EFalse;
+			}
+
+		// Now compare the actual element.
+		TPositionQualityItem::TResult res;
+		if (KErrNone != aQualitySideA.Compare(aQualitySideB, i, res))
+			{
+			return EFalse;	
+			}
+		if (TPositionQualityItem::EIsEqual != res)
+			{
+			return EFalse;
+			}
+		}
+
+	return ETrue;	
+	}
+
+
+/**
+ *  Verifies that the supplied position is 'reasonable'
+ *
+ */
+EXPORT_C TBool T_LbsUtils::Verify_PositionIsValid(TPositionInfo& aPosInfo)
+	{
+	TBool valid = TRUE;
+	TPosition pos;
+	TReal32 alt;
+	TReal64 lat, longt;
+	
+	aPosInfo.GetPosition(pos);
+	
+	alt = pos.Altitude();
+	lat = pos.Latitude();
+	longt = pos.Longitude();
+	
+	// TO DO figure out what values are reasonable here (in Milton somewhere!?)
+	// We could use the normal verify posinfo stuff, and check to see if the values are roughly equal.
+	// Either update this func (add a parameter) or new func like the compare posinfo func we have
+	if(alt == 0 || lat == 0 || longt == 0)
+		{
+		valid = FALSE;
+		}
+	
+	
+	return valid;
+	}
+
+
+// May not be required.
+//EXPORT_C void T_LbsUtils::CreateSimpleAssistanceData(/*TLbsAssistanceDataGroup aDataMask, RDataReaderRootBase& aGpsRefTimeReader*/)
+//	{
+
+//	}
+
+/** Ensure the simple assistance data is correct. Typically the data is given by the simple
+	assistance data provider module used by the Net Sim.
+	
+@param aRefTimeReader The assistance data reader which holds the reference time data, the 
+						reader must be opened (use OpenL()) before calling this function.
+*/
+EXPORT_C TBool T_LbsUtils::VerifySimpleAssistanceData(RUEPositioningGpsReferenceTimeReader& aRefTimeReader)
+	{    
+	TUint week;
+	TUint tow1MSec;	                                            
+
+	// Access the reference time values.
+	aRefTimeReader.GetField(TUEPositioningGpsReferenceTime::EGpsWeek, week);
+	aRefTimeReader.GetField(TUEPositioningGpsReferenceTime::EGpsTow1Msec, tow1MSec);
+			
+	// Verify the reference time values.
+	TBool passed = ETrue;
+	
+	passed &= (week == KAssistanceData_RefTime_Week);
+	passed &= (tow1MSec == KAssistanceData_RefTime_Tow1MSec);
+
+	return passed;
+	}
+
+/** Create the module information depending on module id(i'e either agps_manager or network location manager) 
+    Fills a module info class/structure with values depending on the module id. 
+
+    @param  aModuleId       module id within the ini file
+    @param  aModInfo		The modified module info structure.
+*/
+EXPORT_C void T_LbsUtils::Create_ModuleInfoL(TPositionModuleId aModuleId, TPositionModuleInfo& aModInfo)
+
+	{  
+	   TPositionQuality posQuality;
+	
+	// Use these values if the module is a-gps manager 
+		if (aModuleId == (TUid::Uid(APGS_MODINFO_MODULE_ID)))
+		 {
+		 aModInfo.SetModuleId(TUid::Uid(APGS_MODINFO_MODULE_ID));
+	     aModInfo.SetIsAvailable(AGPS_MODINFO_IS_AVAILABLE);
+	     aModInfo.SetModuleName(AGPS_MODINFO_MOD_NAME);
+	     aModInfo.SetTechnologyType(AGPS_MODINFO_TECHNOLOGY_TYPE);
+	     aModInfo.SetDeviceLocation(AGPS_MODINFO_DEVICE_LOCATION);
+	     aModInfo.SetCapabilities(AGPS_MODINFO_CAPABILITIES);
+	      
+	     // Classes Supported - this is a binary bitmap, but support for each class 
+    	// has to be set individually.
+		
+	 	TInt supportedClasses = AGPS_MODINFO_CLASSES_SUPPORTED_POSITION_FAMILY; 
+    	TPositionClassFamily currentClass = EPositionInfoFamily;
+    	while(currentClass <= EPositionUpdateOptionsFamily)
+        	{
+        	aModInfo.SetClassesSupported(currentClass, supportedClasses & 1); 
+        	supportedClasses >>= 1;
+        	currentClass = static_cast<TPositionClassFamily>(static_cast<TInt>(currentClass) + 1);   		
+        	}
+	     	     
+	     aModInfo.SetVersion(AGPS_MODINFO_VERSION);
+    	 posQuality.SetTimeToFirstFix(AGPS_MODINFO_TIME_TO_FIRST_FIX);
+	     posQuality.SetTimeToNextFix(AGPS_MODINFO_TIME_TO_NEXT_FIX);
+    	 posQuality.SetHorizontalAccuracy(AGPS_MODINFO_HORIZONTAL_ACCURACY);
+	     posQuality.SetVerticalAccuracy(AGPS_MODINFO_VERTICAL_ACCURACY);
+    	 posQuality.SetCostIndicator(AGPS_MODINFO_COST_INDICATOR);
+	     posQuality.SetPowerConsumption(AGPS_MODINFO_POWER_CONSUMPTION);
+       	 aModInfo.SetPositionQuality(posQuality);
+      	 }
+	
+	//need to change after network location manager module is avaliable
+	//Use these values if the module is network location manager
+	   else if(aModuleId ==(TUid::Uid(NETWORK_MODINFO_MODULE_ID)))
+		   {
+		   aModInfo.SetModuleId(TUid::Uid(NETWORK_MODINFO_MODULE_ID));
+	       aModInfo.SetIsAvailable(NETWORK_MODINFO_IS_AVAILABLE);
+	       aModInfo.SetModuleName(NETWORK_MODINFO_MOD_NAME);
+	       aModInfo.SetTechnologyType(NETWORK_MODINFO_TECHNOLOGY_TYPE);
+	       aModInfo.SetDeviceLocation(NETWORK_MODINFO_DEVICE_LOCATION);
+	       aModInfo.SetCapabilities(NETWORK_MODINFO_CAPABILITIES);
+	       // Classes Supported - this is a binary bitmap, but support for each class 
+    	   // has to be set individually.
+		
+	 	   TInt supportedClasses = NETWORK_MODINFO_CLASSES_SUPPORTED_POSITION_FAMILY; 
+    	   TPositionClassFamily currentClass = EPositionInfoFamily;
+    	   while(currentClass <= EPositionUpdateOptionsFamily)
+        	{
+        	aModInfo.SetClassesSupported(currentClass, supportedClasses & 1); 
+        	supportedClasses >>= 1;
+        	currentClass = static_cast<TPositionClassFamily>(static_cast<TInt>(currentClass) + 1);   		
+        	}
+	      	      
+	       aModInfo.SetVersion(NETWORK_MODINFO_VERSION);
+    	   posQuality.SetTimeToFirstFix(NETWORK_MODINFO_TIME_TO_FIRST_FIX);
+	       posQuality.SetTimeToNextFix(NETWORK_MODINFO_TIME_TO_NEXT_FIX);
+    	   posQuality.SetHorizontalAccuracy(NETWORK_MODINFO_HORIZONTAL_ACCURACY);
+	       posQuality.SetVerticalAccuracy(NETWORK_MODINFO_VERTICAL_ACCURACY);
+    	   posQuality.SetCostIndicator(NETWORK_MODINFO_COST_INDICATOR);
+	       posQuality.SetPowerConsumption(NETWORK_MODINFO_POWER_CONSUMPTION); 
+	       aModInfo.SetPositionQuality(posQuality);
+		  }
+	  else
+	     {
+	       	User::Leave(KErrArgument);
+	      
+	     }  
+	 }
+
+TInt T_LbsUtils::GetModIdByTechnology(RPositionServer& aServer, TPositionModuleInfo::TTechnologyType aTechnologyType, TPositionModuleId& aModuleId)
+/** Searchs for a module which matches the required technology type. Once found the module id of the matched module
+	is given. The first module found which supports the technology will be returned.
+
+@param aServer			A position server. A client must have a connection with the server.
+@param aTechnologyType	The technology to match.
+@param aModuleId		The returned module id of the module which supports the required technology.
+@return					Err code:	KErrNone it module found.
+									KErrNotFound if no module is found which matches the required technology.
+									Any other system errors.
+*/
+{
+	TInt err;
+	TUint numMods;
+
+	err = aServer.GetNumModules(numMods);
+	if (KErrNone == err)
+		{
+		TInt i = 0;
+		TPositionModuleInfo	modInfo;
+		
+		// Look at each module until we find the required technology type.
+		while (i < numMods)
+			{
+			err = aServer.GetModuleInfoByIndex(i, modInfo);
+		
+			// Found it.
+			if (modInfo.TechnologyType() == aTechnologyType)
+				{
+				aModuleId = modInfo.ModuleId();
+				
+				return err;
+				}
+			i++;
+			}
+		}
+		
+	else
+	{
+		return err;
+	}
+	
+	return KErrNotFound;
+}
+
+
+/**
+ * Method for comparing base class member variables in Logevent types
+ */
+TBool T_LbsUtils::Compare_LogBase(const CLbsLogEvent& aLogEventSideA, const CLbsLogEvent& aLogEventSideB)
+{
+	if(aLogEventSideA.Direction() != aLogEventSideB.Direction())
+		return EFalse;
+	
+	if(aLogEventSideA.EventType() != aLogEventSideB.EventType())
+		return EFalse;
+	
+	if(aLogEventSideA.RequestOutcome() != aLogEventSideB.RequestOutcome())
+		return EFalse;
+
+	if(aLogEventSideA.IsCostInformationAvailable() != aLogEventSideB.IsCostInformationAvailable())
+		return EFalse;
+	else
+		{
+		//check cost info for each side
+		if(aLogEventSideA.CostInformation() != aLogEventSideB.CostInformation())
+		return EFalse;
+		}
+		
+	TPositionInfoBase* sideAPosInfo = reinterpret_cast<TPositionInfoBase*>(aLogEventSideA.PositionInfo());
+	TPositionInfoBase* sideBPosInfo = reinterpret_cast<TPositionInfoBase*>(aLogEventSideB.PositionInfo());
+	if(sideAPosInfo != NULL)
+		{
+		// If the actual log has a non-NULL posinfo...
+		if((*aLogEventSideA.PositionInfo()).ModuleId() != (*aLogEventSideB.PositionInfo()).ModuleId())
+			return EFalse;	
+		
+		if(!Compare_PosInfo(*aLogEventSideA.PositionInfo(), *aLogEventSideB.PositionInfo()))
+			return EFalse;	
+		}
+		else
+		{	
+			// else cheach that both sides have NULL
+			if(!(sideAPosInfo == NULL && sideBPosInfo == NULL))
+				return EFalse;	
+		}
+		
+
+
+return ETrue;
+}
+/**
+ * Method for comparing SelfLocateLog
+ */
+EXPORT_C TBool T_LbsUtils::Compare_SelfLocateLog(const CLbsSelfLocateLogEvent& aSelfLocateLogSideA, const CLbsSelfLocateLogEvent& aSelfLocateLogSideB)
+{
+	//Compare base class member variables
+	if(!Compare_LogBase(aSelfLocateLogSideA, aSelfLocateLogSideB))
+		return EFalse;
+	
+	if(aSelfLocateLogSideA.LocalApp() != aSelfLocateLogSideB.LocalApp())
+		return EFalse;
+	
+	return ETrue;
+}
+
+/**
+ * Method for comparing NetworkLocateLog
+ */
+EXPORT_C TBool T_LbsUtils::Compare_NetworkLocateLog(const CLbsNetworkLocateLogEvent& aNetworkLocateLogSideA, const CLbsNetworkLocateLogEvent& aNetworkLocateLogSideB)
+{
+	//Compare base class member variables
+	if(!Compare_LogBase(aNetworkLocateLogSideA, aNetworkLocateLogSideB))
+		return EFalse;
+	
+	if(aNetworkLocateLogSideA.LocalApp() != aNetworkLocateLogSideB.LocalApp())
+		return EFalse;
+	
+	return ETrue;
+}
+
+/**
+ * Method for comparing ExternalLocateLog
+ */
+EXPORT_C TBool T_LbsUtils::Compare_ExternalLocateLog(const CLbsExternalLocateLogEvent& aExternalLocateLogSideA, const CLbsExternalLocateLogEvent& aExternalLocateLogSideB)
+{
+	//Compare base class member variables
+	if(!Compare_LogBase(aExternalLocateLogSideA, aExternalLocateLogSideB))
+		return EFalse;
+	
+	if(!Compare_PosInfo(*aExternalLocateLogSideA.ReferenceLocation(), *aExternalLocateLogSideB.ReferenceLocation()))
+			return EFalse;				
+	
+	if(aExternalLocateLogSideA.RequestOriginator() != aExternalLocateLogSideB.RequestOriginator())
+		return EFalse;
+	
+	if(!Compare_ExternalRequestPrivacyRequestParams(aExternalLocateLogSideA.PrivacyRequestParams(), aExternalLocateLogSideB.PrivacyRequestParams()))
+		return EFalse;
+	
+	if(!Compare_ExternalRequestPrivacyResponseParams(aExternalLocateLogSideA.PrivacyResponseParams(), aExternalLocateLogSideB.PrivacyResponseParams()))
+		return EFalse;
+	
+return ETrue;
+}
+
+
+
+/**
+ * Method for comparing X3PLog
+ */
+EXPORT_C TBool T_LbsUtils::Compare_TransmitLocationLog(const CLbsTransmitLocationLogEvent& aX3PLogSideA, const CLbsTransmitLocationLogEvent& aX3PLogSideB)
+{
+	//Compare base class member variables
+	if(!Compare_LogBase(aX3PLogSideA, aX3PLogSideB))
+		return EFalse;
+	
+	if(aX3PLogSideA.X3PApp() != aX3PLogSideB.X3PApp())
+		return EFalse;
+	
+	if(!Compare_Destinations(aX3PLogSideA.Destination(), aX3PLogSideB.Destination()))
+		return EFalse;
+	
+	return ETrue;
+}
+
+
+/**
+ * Method for comparing AssistanceDataLog
+ */
+EXPORT_C TBool T_LbsUtils::Compare_AssistanceDataLog(const CLbsAssistanceDataLogEvent& aAssistanceDataLogSideA, const CLbsAssistanceDataLogEvent& aAssistanceDataLogSideB)
+{
+	//Compare base class member variables
+	if(!Compare_LogBase(aAssistanceDataLogSideA, aAssistanceDataLogSideB))
+		return EFalse;
+	
+	if(aAssistanceDataLogSideA.RequestAssistanceDataType() != aAssistanceDataLogSideB.RequestAssistanceDataType())
+		return EFalse;
+	
+
+	if(aAssistanceDataLogSideA.ReceiveAssistanceDataType() != aAssistanceDataLogSideB.ReceiveAssistanceDataType())
+		return EFalse;	
+	
+	return ETrue;
+}
+
+
+/**
+ * Method needed to compare external locate logs.
+ */
+TBool T_LbsUtils::Compare_ExternalRequestPrivacyRequestParams(const TLbsLoggingPrivacyRequestParams& aLogPrivacyRequestParamsSideA, const TLbsLoggingPrivacyRequestParams& aLogPrivacyRequestParamsSideB)
+{
+	if(aLogPrivacyRequestParamsSideA.iSessionId != aLogPrivacyRequestParamsSideB.iSessionId)
+		return EFalse;
+	
+	if(!Compare_ExternalRequestInfo(aLogPrivacyRequestParamsSideA.iRequestInfo, aLogPrivacyRequestParamsSideB.iRequestInfo))
+		return EFalse;
+	
+	if(!Compare_ExternalRequestPrivacy(aLogPrivacyRequestParamsSideA.iRequestPrivacy, aLogPrivacyRequestParamsSideB.iRequestPrivacy))
+		return EFalse;
+	
+	
+	
+	return ETrue;
+}
+
+
+/**
+ * Method needed to compare external locate logs.
+ * Compares TLbsExternalRequestInfo class.
+ */
+TBool T_LbsUtils::Compare_ExternalRequestInfo(const TLbsExternalRequestInfo& aExternalRequestInfoSideA, const TLbsExternalRequestInfo& aExternalRequestInfoSideB)
+{
+	TLbsRequesterId requesterIdSideA, requesterIdSideB;
+	TLbsClientName clientNameSideA, clientNameSideB;
+	TLbsClientExternalId clientExternalIdSideA, clientExternalIdSideB;
+	
+	aExternalRequestInfoSideA.GetRequesterId(requesterIdSideA);
+	aExternalRequestInfoSideA.GetClientName(clientNameSideA);
+	aExternalRequestInfoSideA.GetClientExternalId(clientExternalIdSideA);	
+	
+	aExternalRequestInfoSideB.GetRequesterId(requesterIdSideB);
+	aExternalRequestInfoSideB.GetClientName(clientNameSideB);
+	aExternalRequestInfoSideB.GetClientExternalId(clientExternalIdSideB);	
+	
+	// If these values are different, then return false
+	if(requesterIdSideA.Compare(requesterIdSideB))	// Should return 0 if equal
+		return EFalse;
+	
+	if(clientNameSideA.Compare(clientNameSideB))
+		return EFalse;
+		
+	if(clientExternalIdSideA.Compare(clientExternalIdSideB))
+		return EFalse;
+	
+	
+	return ETrue;
+}
+
+
+/**
+ * Method needed to compare external locate logs.
+ * Compares TLbsNetPosRequestPrivacy class.
+ */
+TBool T_LbsUtils::Compare_ExternalRequestPrivacy(const TLbsNetPosRequestPrivacy& aExternalRequestPrivacySideA, const TLbsNetPosRequestPrivacy& aExternalRequestPrivacySideB)
+{
+	if(aExternalRequestPrivacySideA.RequestAdvice() != aExternalRequestPrivacySideB.RequestAdvice())
+		return EFalse;
+	
+	if(aExternalRequestPrivacySideA.RequestAction() != aExternalRequestPrivacySideB.RequestAction())
+		return EFalse;
+	
+	return ETrue;
+}
+
+
+/**
+ * Method needed to compare external locate logs.
+ * Compares TPrivacyResponseParams class.
+ */
+TBool T_LbsUtils::Compare_ExternalRequestPrivacyResponseParams(const TLbsLoggingPrivacyResponseParams& aExternalRequestPrivacyResponseSideA, const TLbsLoggingPrivacyResponseParams& aExternalRequestPrivacyResponseSideB)
+{
+	if(aExternalRequestPrivacyResponseSideA.iSessionId != aExternalRequestPrivacyResponseSideB.iSessionId)
+		return EFalse;
+	
+	if(aExternalRequestPrivacyResponseSideA.iResult != aExternalRequestPrivacyResponseSideB.iResult)
+		return EFalse;
+		
+	return ETrue;
+}
+
+/**
+ * Method needed to Transmit to 3rd party destinations
+ * Compares TDesC16.
+ */
+TBool T_LbsUtils::Compare_Destinations(TDesC16& aDestinationFromRealLog, TDesC16& aDestinationFromExpectedLog)
+	{
+	if(aDestinationFromRealLog != aDestinationFromExpectedLog)
+		return EFalse;
+	
+	return ETrue;
+	}
+