diff -r e8c1ea2c6496 -r 8758140453c0 lbs/lbstestutils/src/tlbsutils.cpp --- /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 +#include +#include + +// Lbs includes +#include +#include + + +// 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& 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& 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& 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& 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 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 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 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(aPosInfoSideA); + const TPositionInfo& posInfoSideB = reinterpret_cast(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(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& aPosInfoArrSideA, RPointerArray& aPosInfoArrSideB) + { + return Compare_PosInfoArr(aPosInfoArrSideA, aPosInfoArrSideB, EExactAccuracy); + } + +EXPORT_C TBool T_LbsUtils::Compare_PosInfoArr(RPointerArray& aPosInfoArrSideA, RPointerArray& 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(aPosInfoArrSideA[i]); + posInfoB = reinterpret_cast(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& 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(i)) != aModInfoSideB.ClassesSupported(static_cast(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 modNameSideA; + TBuf 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(static_cast(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(static_cast(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(aLogEventSideA.PositionInfo()); + TPositionInfoBase* sideBPosInfo = reinterpret_cast(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; + } +