/** Calculates a difference between the system UTC time and the GPS based UTC time.
Accuracy of the calculations is affected by:
   - time required to process the satellite information in the GPS HW
   - time required to transfer the information over a HW link from the GPS HW to a mobile phone
   - time required to receive the information by a Symbian OS drivers and decode by the AGPS
     integration module

@param aSatInfo A satellite information with the GPS based UTC time
@param aTimeCorr A time correction that must be applied to the System UTC time. Not valid if the method returns an error.
@return KErrNone if sucedded. 
        KErrNotSupported if the satellite (GPS based UTC time) or the position 
        reception time is not present (0).
@see TPositionSatelliteInfo
@internalComponent
*/
TInt CAutoClockAdjust::CalculateTimeCorrection(const TPositionSatelliteInfo &aSatInfo, TTimeIntervalMicroSeconds &aTimeCorr)
	{
	LBSLOG(ELogP1, "CAutoClockAdjust::CalculateTimeCorrection()\n");
	// The System UTC time when the location has been received from a GPS
	TTime recTime;
	// GPS based UTC time (satellite time)
	TTime satTime;

	TPosition pos;
	TInt err = KErrNone;
		
	aSatInfo.GetPosition(pos);
	recTime = pos.Time();
	satTime = aSatInfo.SatelliteTime();
	
	if ((recTime == 0) || (satTime == 0))
		{
		err = KErrNotSupported;
		}
	else
		{
		aTimeCorr = satTime.MicroSecondsFrom(recTime);
		}
	
	return err;
	}
/** Adjusts system time if required. The decision whether the adjustment is needed or not
is based on the following criterias:
 - satellite time must be present in the location update
 - time threshold must be exceeded
 - time from a last adjustment is greater than a defined interval.
 
@param aStatus An error code.
@param TPositionSatelliteInfo Position and time information. 
							  If clock adjustment takes place the TPosition::iTime is 
							  re-set to the satellite time.
@see CLbsAdmin
@see TPositionSatelliteInfo
*/
void CAutoClockAdjust::LocationUpdate(TInt aStatus, TPositionSatelliteInfo& aPosInfo)
	{
	LBSLOG(ELogP1, "CAutoClockAdjust::LocationUpdate()\n");
	TTimeIntervalMicroSeconds timeCorr;
	TTime sysTime;
	TInt err;
	
	// If adjustment on, no error, and satellite information present
	if ((iClockAdjustSetting == CLbsAdmin::EClockAdjustOn) && (aStatus == KErrNone) &&
	    ((aPosInfo.PositionClassType() & EPositionSatelliteInfoClass) == EPositionSatelliteInfoClass))
		{
		// Is is time do do another time adjustment?
		sysTime.UniversalTime();
		if (Abs(sysTime.MicroSecondsFrom(iLastAdjustment).Int64()) > (1000*iAdjustInterval))
			{
			const TPositionSatelliteInfo& satInfo = static_cast<const TPositionSatelliteInfo&>(aPosInfo);
			err = CalculateTimeCorrection(satInfo, timeCorr);
			if (err == KErrNone)
				{
				// Is threshold exceeded? 
				if (Abs(timeCorr.Int64()) > (1000*iAdjustThreshold))
					{
					sysTime.UniversalTime();
					sysTime += timeCorr;
					LBSLOG(ELogP9, "->S CGpsSetClockBase::SetUTCTime() ClockModule\n");
					LBSLOG5(ELogP9, "  > TTime sysTime  = %02d:%02d:%02d.%06d\n", sysTime.DateTime().Hour(), 
																				sysTime.DateTime().Minute(),
																				sysTime.DateTime().Second(),
																				sysTime.DateTime().MicroSecond());

					err = iSetClockImpl->SetUTCTime(sysTime);
					LBSLOG2(ELogP9, "  Return  = %d\n", err);

					if (err == KErrNone)
						{				
						// Sync the position time with the satellite time
						// to avoid re-adjusting the system time by the manual clock adjustment component.
						TPosition pos;
						aPosInfo.GetPosition(pos);
						pos.SetTime(aPosInfo.SatelliteTime());
						aPosInfo.SetPosition(pos);
						LBSLOG2(ELogP2, "ACTION: Clock Adjusted by %ld\n", timeCorr.Int64());
						}
					}
					
				if (err == KErrNone)
					{				
					// Remember the current time even if threshold not exceeded
					iLastAdjustment = sysTime;
					}
				else
					{
					LBSLOG_WARN2(ELogP3, "Clock Adjustment failed. Error: %d\n", err);
					}
				}
			}
		}
	}
예제 #3
0
void CLcfPsyDummy3::GetPositionSatelliteInfoL(TPositionInfoBase& aPosInfo)
    {
    TPositionSatelliteInfo* satInfo = static_cast<TPositionSatelliteInfo*>(&aPosInfo);

    // prepare data
    satInfo->ClearSatellitesInView();

    satInfo->SetHorizontalDoP(DUMMY_SAT_INFO_HDOP);
    satInfo->SetVerticalDoP(DUMMY_SAT_INFO_VDOP);
    satInfo->SetTimeDoP(DUMMY_SAT_INFO_TDOP);
    satInfo->SetSatelliteTime(DUMMY_SAT_INFO_TIME);

    TSatelliteData satData;

    // first satellite
    satData.SetAzimuth(DUMMY_AZIMUTH1);
    satData.SetElevation(DUMMY_ELEVATION1);
    satData.SetIsUsed(DUMMY_IS_USED1);
    satData.SetSatelliteId(DUMMY_SATELLITE_ID1);
    satData.SetSignalStrength(DUMMY_SIGNAL_STRENGTH1);
    // add to info
    satInfo->AppendSatelliteData(satData);

    // second satellite
    satData.SetAzimuth(DUMMY_AZIMUTH2);
    satData.SetElevation(DUMMY_ELEVATION2);
    satData.SetIsUsed(DUMMY_IS_USED2);
    satData.SetSatelliteId(DUMMY_SATELLITE_ID2);
    satData.SetSignalStrength(DUMMY_SIGNAL_STRENGTH2);
    // add to info
    satInfo->AppendSatelliteData(satData);
    }
void CT_LbsClientPosTp2::CheckPositionSatelliteInfoL(TPositionSatelliteInfo& aSatelliteInfo)
	{
	CheckPositionCourseInfoL(aSatelliteInfo);
	if((TUint)aSatelliteInfo.NumSatellitesUsed() != KNumberOfSatellitesUsed ||
	   aSatelliteInfo.SatelliteTime() != TTime(KSatelliteTime) ||
	   (TUint)aSatelliteInfo.NumSatellitesInView() != KNumberOfSatellitesInView ||
	   aSatelliteInfo.HorizontalDoP() != KHorizontalDoPValue ||
	   aSatelliteInfo.VerticalDoP() != KVerticalDoPValue ||
	   aSatelliteInfo.TimeDoP() != KTimeDoPValue)
	   {
		_LIT(KErrBasicSat, "Basic satellite information not correct");
		LogErrorAndLeaveL(KErrBasicSat);
		}
		TInt sats = aSatelliteInfo.NumSatellitesInView();
	for (int i = 0; i < sats; i++)
		{
		TSatelliteData satelliteData;
		TInt err = aSatelliteInfo.GetSatelliteData(i,satelliteData);
		if (err != KErrNone)
			{
			_LIT(KErrGetSat, "Not possible to get satellite data, error code = %d");
			TBuf<100> buf;
			buf.Format(KErrGetSat, err);
			LogErrorAndLeaveL(buf);
			}
		if ( (i%2) == 0 )
			{
			if(	satelliteData.SatelliteId() != (KSatelliteId +i) ||
				satelliteData.Azimuth() != KAzimuth ||
				satelliteData.Elevation() != KElevation ||
				satelliteData.IsUsed() != KIsUsed ||
				satelliteData.SignalStrength() != KSignalStrength)
				{
				_LIT(KErrSatDataEven, "Incorrect satellite data on even satellites");
				LogErrorAndLeaveL(KErrSatDataEven);
				}
			}
		else
			{
			if(	satelliteData.SatelliteId() != (KSatelliteId +i) ||
				satelliteData.Azimuth() != KAzimuthOdd ||
				satelliteData.Elevation() != KElevationOdd ||
				satelliteData.IsUsed() != KIsUsedOdd ||
				satelliteData.SignalStrength() != KSignalStrengthOdd)
				{
				_LIT(KErrSatDataOdd, "Incorrect satellite data on odd satellites");
				LogErrorAndLeaveL(KErrSatDataOdd);
				}
			}

		}
	}
예제 #5
0
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);
		}
	}
// ---------------------------------------------------------
// CPosPSYClearPositionDataTest::CheckSatelliteInfoClearsL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//    
void CPosPSYClearPositionDataTest::CheckSatelliteInfoClearsL()
    {
    TBool allIsCleared = ETrue;
	TPositionSatelliteInfo* satInfo = static_cast<TPositionSatelliteInfo*> (iPosInfo);

	if (satInfo->SatelliteTime() == KSatelliteTime)
		{
		_LIT(KError, "Satellite Time was not cleared for TPositionSatelliteInfo.");
        AddTestResultL(KError, EErrorMessage);
		allIsCleared = EFalse;
		}
	if (!Math::IsNaN(satInfo->HorizontalDoP()))
		{
		if (satInfo->HorizontalDoP() == KSatelliteHorizontalDoP)
			{	
			_LIT(KError, "Horizontal DoP was not cleared for TPositionSatelliteInfo.");
			AddTestResultL(KError, EErrorMessage);
			allIsCleared = EFalse;
			}
		}
	if (!Math::IsNaN(satInfo->VerticalDoP()))
		{
		if (satInfo->VerticalDoP() == KSatelliteVerticalDoP)
			{
			_LIT(KError, "Vertical DoP was not cleared for TPositionSatelliteInfo.");
			AddTestResultL(KError, EErrorMessage);
			allIsCleared = EFalse;
			}
		}
	if (!Math::IsNaN(satInfo->TimeDoP()))
		{
		if (satInfo->TimeDoP() == KSatelliteTimeDoP)
			{
			_LIT(KError, "Time DoP was not cleared for TPositionSatelliteInfo.");
			AddTestResultL(KError, EErrorMessage);
			allIsCleared = EFalse;
			}
		}

	TBool satelliteDataNotCleared = EFalse;
	for (TInt  i = 0; i < KSatelliteNumInView; i++)
		{
		TSatelliteData satellite;
		TInt error = satInfo->GetSatelliteData(i, satellite);
		if (error != KErrNotFound)
			{
			if (!Math::IsNaN(satellite.Azimuth()))
				{
				if (satellite.Azimuth() == KAzimuth)
					{
					satelliteDataNotCleared = ETrue;
					}
				}
			if (!Math::IsNaN(satellite.Elevation()))
				{
				if (satellite.Elevation() == KElevation)
					{
					satelliteDataNotCleared = ETrue;
					}
				}

			if (satellite.SatelliteId() == KSatelliteId ||
				satellite.SignalStrength() == KSignalStrength)
				{
				satelliteDataNotCleared = ETrue;
				}
			}
		}
	
	if (satelliteDataNotCleared)
		{
		_LIT(KError, "Satellite Data was not cleared for all satellites in TPositionSatelliteInfo.");
		AddTestResultL(KError, EErrorMessage);
		allIsCleared = EFalse;
		}

	if (allIsCleared)
		{
		_LIT(KInfo, "All fields were cleared for TPositionSatelliteInfo.");
		AddTestResultL(KInfo, EInfoMessage);
		}
    }
// ---------------------------------------------------------
// CPosPSYClearPositionDataTest::HandlePositionCompleteL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosPSYClearPositionDataTest::HandlePositionCompleteL(
	TInt aCompleteCode,
	TTimeIntervalMicroSeconds /*aRequestTime*/)
	{
	if (iTestStatus == KErrCancel)
		{
		CompleteClearPositionDataTest(iTestStatus);
		return;
		}

	if (iCurrentTestClass == 0 || iCurrentTestClass == EPositionInfoClass)
		{
		_LIT(KTitleTestInfo, "==== Testing clearing of TPositionInfo ====");
		AddTestResultL(KTitleTestInfo, EDisplayMessage);
		if (iPSYInfo.ClassesSupported() & EPositionInfoClass && 
			!(iClassesTested & EPositionInfoClass))
			{
			iCurrentTestClass = EPositionInfoClass;
			
			if (iRequestNumber == 0) 
				{
				iClassesTested |= EPositionInfoClass;
				PerformTestL(aCompleteCode);
				}
			}
		else
			{
			_LIT(KTestInfo, "Clearing of position data tests not performed with TPositionInfo because PSY didn't support it.");
			AddTestResultL(KTestInfo, EInfoMessage);
			}
		}

	if (iCurrentTestClass == 0 || iCurrentTestClass == EPositionGenericInfoClass)
		{
		if (iRequestNumber == 0)
			{
			_LIT(KTestInfoGeneric, "==== Testing clearing of HPositionGenericInfo ====");
			AddTestResultL(KTestInfoGeneric, EDisplayMessage);
			}
		if (iPSYInfo.ClassesSupported() & EPositionGenericInfoClass && 
			!(iClassesTested & EPositionGenericInfoClass))
			{
			iCurrentTestClass = EPositionGenericInfoClass;
			
			if (iRequestNumber == 1) 
				{
				iClassesTested |= EPositionGenericInfoClass;
				PerformTestL(aCompleteCode);	
				}
			else
				{
				HPositionGenericInfo* genInfo = HPositionGenericInfo::NewLC(KPositionGenericInfoDefaultBufferSize * 2, 
													  KPositionGenericInfoDefaultMaxFields * 2);

				SetHPositionGenericInfoDataL(*genInfo);
				CleanupStack::Pop(genInfo);
				genInfo->SetPosition(iPosition);
				iPosInfo = static_cast<TPositionInfo*> (genInfo);
				iRequester->MakeRequest(*iPosInfo);
				iRequestNumber++;
				}
			}
		else
			{
			_LIT(KTestInfo, "Clearing of position data tests not performed with HPositionGenericInfo because PSY didn't support it.");
			AddTestResultL(KTestInfo, EInfoMessage);
			}
		}
    
	if (iCurrentTestClass == 0 || iCurrentTestClass == EPositionCourseInfoClass)
		{
		if (iRequestNumber == 0)
			{
			_LIT(KTestInfo, "==== Testing clearing of TPositionCourseInfo ====");
			AddTestResultL(KTestInfo, EDisplayMessage);
			}
		if (iPSYInfo.ClassesSupported() & EPositionCourseInfoClass && 
			!(iClassesTested & EPositionCourseInfoClass))
			{
			iCurrentTestClass = EPositionCourseInfoClass;
			if (iRequestNumber == 1) 
				{
				iClassesTested |= EPositionCourseInfoClass;
				PerformTestL(aCompleteCode);
				}
			else
				{
				TPositionCourseInfo* courseInfo = new (ELeave) TPositionCourseInfo;
				courseInfo->SetCourse(iCourse);
				courseInfo->SetPosition(iPosition);
				iPosInfo = static_cast<TPositionInfo*> (courseInfo);
				iRequester->MakeRequest(*iPosInfo);
				iRequestNumber++;
				}
			}
		else
			{
			_LIT(KTestInfo, "Clearing of position data tests not performed with TPositionCourseInfo because PSY didn't support it.");
			AddTestResultL(KTestInfo, EInfoMessage);
			}
		}

	if (iCurrentTestClass == 0 || iCurrentTestClass == EPositionSatelliteInfoClass)
		{
		if (iRequestNumber == 0)
			{
			_LIT(KTestInfo, "==== Testing clearing of TPositionSatelliteInfo ====");
			AddTestResultL(KTestInfo, EDisplayMessage);
			}
		if (iPSYInfo.ClassesSupported() & EPositionSatelliteInfoClass &&
			!(iClassesTested & EPositionSatelliteInfoClass))
			{
			iCurrentTestClass = EPositionSatelliteInfoClass;
			if (iRequestNumber == 1)
				{
				iClassesTested |= EPositionSatelliteInfoClass;
				PerformTestL(aCompleteCode);
				}
			else
				{
				TPositionSatelliteInfo* satInfo = new (ELeave) TPositionSatelliteInfo;
				
				satInfo->SetSatelliteTime(KSatelliteTime);
				satInfo->SetHorizontalDoP(KSatelliteHorizontalDoP);
				satInfo->SetVerticalDoP(KSatelliteVerticalDoP);
				satInfo->SetTimeDoP(KSatelliteTimeDoP);

				for (TInt  i = 0; i < KSatelliteNumInView; i++)
					{
					TSatelliteData satellite;
					satellite.SetSatelliteId(KSatelliteId+i);
					satellite.SetAzimuth(KAzimuth);
					satellite.SetElevation(KElevation);
					satellite.SetIsUsed(KIsUsed);
					satellite.SetSignalStrength(KSignalStrength);
	
					satInfo->AppendSatelliteData(satellite);
					}
				
				satInfo->SetCourse(iCourse);
				satInfo->SetPosition(iPosition);
				iPosInfo = static_cast<TPositionInfo*> (satInfo);
				iRequester->MakeRequest(*iPosInfo);
				iRequestNumber++;
				}
			}
		else
			{
			_LIT(KTestInfo, "Clearing of position data tests not performed with TPositionSatelliteInfo because PSY didn't support it.");
			AddTestResultL(KTestInfo, EInfoMessage);
			}
		}
	}
void XQLocationPrivate::DeliverPositionerResults(TPositionSatelliteInfo aPositionInfo)
{
    TPosition pos; 
    aPositionInfo.GetPosition(pos);
    
    // Handle speed reporting
    float speed = 0;
    if (speedAvailable) {
        // Positioning module is able to offer speed information
        TCourse course;
        aPositionInfo.GetCourse(course);
        speed = course.Speed();
        if (isnan(speed)) {
            speed = 0;
        }
    } else {
        // Positioning module does not offer speed information
        // => Speed is calculated using position information & timestamps
        TTime posTime;
        TTimeIntervalSeconds interval;
        for (int i = iPositions.Count()-1 ; i >= 0; i--) {
            if (pos.Time().SecondsFrom(iPositions[i].Time(),interval) == KErrNone) {
                if (interval.Int() > 10) {
                    pos.Speed(iPositions[i], speed);
                    break;
                }
            }
        }
        while (iPositions.Count() > 0) {
            if (pos.Time().SecondsFrom(iPositions[0].Time(),interval) == KErrNone) {
                if (interval.Int() > 60) {
                    iPositions.Remove(0);
                } else {
                    break;
                }
            }
        }
        if (iPositions.Count() > 0) {
    	    if (pos.Time().SecondsFrom(iPositions[iPositions.Count()-1].Time(),interval) == KErrNone) {
                if (interval.Int() > 1) {
                    iPositions.Append(pos);
                }
        	}
        } else {
            iPositions.Append(pos);
        }
        // Accept speed from range 0.01 m/s (0.036 km/h) to 200 m/s (720 km/h)  
        if (speed < 0.01 || speed > 200) {
            speed = 0;
        }
    }
    if (speed != iPreviousSpeed) {
        emit ipParent->speedChanged(speed);
    }
    iPreviousSpeed = speed;
    
    // Handle satellite information reporting
    if (satelliteInfoAvailable) {
        if (aPositionInfo.NumSatellitesInView() != iPreviousNumSatellitesInView) {
            emit ipParent->numberOfSatellitesInViewChanged(aPositionInfo.NumSatellitesInView());
        }
        iPreviousNumSatellitesInView = aPositionInfo.NumSatellitesInView(); 

		if (aPositionInfo.NumSatellitesUsed() != iPreviousNumSatellitesUsed) { 
            emit ipParent->numberOfSatellitesUsedChanged(aPositionInfo.NumSatellitesUsed());
        }
        iPreviousNumSatellitesUsed = aPositionInfo.NumSatellitesUsed();
    }
    
    // Handle position information reporting
    if (iPreviousPosition.Latitude() != pos.Latitude() ||
        iPreviousPosition.Longitude() != pos.Longitude() ||
        iPreviousPosition.Altitude() != pos.Altitude()) {
        if (!isnan(pos.Latitude()) || !isnan(pos.Longitude()) || !isnan(pos.Altitude())) {
            emit ipParent->locationChanged(pos.Latitude(),pos.Longitude(),pos.Altitude(),speed);
        }
        
        if (iPreviousPosition.Latitude() != pos.Latitude()) {
            if (!isnan(pos.Latitude())) {
                emit ipParent->latitudeChanged(pos.Latitude(),pos.HorizontalAccuracy());
            }
        }
        if (iPreviousPosition.Longitude() != pos.Longitude()) {
            if (!isnan(pos.Longitude())) {
                emit ipParent->longitudeChanged(pos.Longitude(),pos.HorizontalAccuracy());
            }
        }
        if (iPreviousPosition.Altitude() != pos.Altitude()) {
            if (!isnan(pos.Altitude())) {
                emit ipParent->altitudeChanged(pos.Altitude(),pos.VerticalAccuracy());
            }
        }
    }
    iPreviousPosition = pos;
    
    if (iSingleUpdate) {
        stopUpdates();
        iSingleUpdate = EFalse;
    }
}
예제 #9
0
void PsyUtils::TPositionInfo2QGeoPositionInfo(TPositionInfoBase &aPosInfoBase, QGeoPositionInfo& aQPosInfo)
{
    if (aPosInfoBase.PositionClassType() & EPositionInfoClass  ||
            aPosInfoBase.PositionClassType() & EPositionSatelliteInfoClass) {
        TPositionInfo *posInfo = static_cast<TPositionInfo*>(&aPosInfoBase);
        TPosition pos;
        QGeoCoordinate  coord;

        posInfo->GetPosition(pos);
        coord.setLatitude(pos.Latitude());
        coord.setLongitude(pos.Longitude());
        coord.setAltitude(pos.Altitude());

        //store the QGeoCoordinate values
        aQPosInfo.setCoordinate(coord);

        TDateTime datetime = pos.Time().DateTime();
        QDateTime dt(QDate(datetime.Year() , datetime.Month() + 1, datetime.Day() + 1),
                     QTime(datetime.Hour() , datetime.Minute(), datetime.Second(),
                           datetime.MicroSecond() / 1000),
                     Qt::UTC);

        //store the time stamp
        aQPosInfo.setTimestamp(dt);

        //store the horizontal accuracy
        aQPosInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy, pos.HorizontalAccuracy());

        //store the vertical accuracy
        aQPosInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, pos.VerticalAccuracy());

        if (aPosInfoBase.PositionClassType() & EPositionSatelliteInfoClass) {
            TCourse course;
            TPositionSatelliteInfo *satInfo = static_cast<TPositionSatelliteInfo*>(&aPosInfoBase);
            satInfo->GetCourse(course);
            aQPosInfo.setAttribute(QGeoPositionInfo::Direction, course.Heading());
            aQPosInfo.setAttribute(QGeoPositionInfo::GroundSpeed, course.Speed());
            aQPosInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, course.VerticalSpeed());
        }
    }

    if (aPosInfoBase.PositionClassType() & EPositionGenericInfoClass) {
        HPositionGenericInfo *genInfo = static_cast<HPositionGenericInfo*>(&aPosInfoBase);
        float val;
        //check for the horizontal speed
        if (genInfo->IsFieldAvailable(EPositionFieldHorizontalSpeed)) {
            genInfo->GetValue(EPositionFieldHorizontalSpeed, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::GroundSpeed, val);
        }
        //check for the vertcal speed
        if (genInfo->IsFieldAvailable(EPositionFieldVerticalSpeed)) {
            genInfo->GetValue(EPositionFieldVerticalSpeed, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, val);
        }

        //check for the magnetic variation
        if (genInfo->IsFieldAvailable(EPositionFieldMagneticCourseError)) {
            genInfo->GetValue(EPositionFieldMagneticCourseError, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::MagneticVariation, val);
        }

        //check for the heading
        if (genInfo->IsFieldAvailable(EPositionFieldHeading)) {
            genInfo->GetValue(EPositionFieldHeading, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::Direction, val);
        }
    }
}
TVerdict CT_LbsHybridUEAssistedX3PAccurateGPS::doTestStepL()
	{
	// Generic test step used to test the LBS Client Notify position update API.
	INFO_PRINTF1(_L("CT_LbsHybridUEAssistedX3PAccurateGPS::doTestStepL()"));

	// Stop the test if the preamble failed
	TESTL(TestStepResult() == EPass);
	
	const TInt KTimeOut = 30*1000*1000;
	const TInt KAdviceSystemStatusTimeout = 40*1000*1000;
	const TInt KSmallTimeOut = 3*1000*1000; 
	
	// >> AdviceSystemStatus(0)
	TESTL(iProxy->WaitForResponse(KAdviceSystemStatusTimeout) == ENetMsgGetCurrentCapabilitiesResponse);
	CLbsNetworkProtocolBase::TLbsSystemStatus status;
	TInt cleanupCnt;
	cleanupCnt = iProxy->GetArgsLC(ENetMsgGetCurrentCapabilitiesResponse, &status);
	TESTL(status == CLbsNetworkProtocolBase::ESystemStatusNone);
	CleanupStack::PopAndDestroy(cleanupCnt);

//Initiate X3P start
	// TransmitPosition()
	_LIT(KThirdParty,"+4407463842101"); 
	const TInt KPriority= 6;
	TLbsTransmitPositionOptions options(TTimeIntervalMicroSeconds(50*1000*1000));
	TRequestStatus refPosStatus=KRequestPending;
	TRequestStatus transPosStatus=KRequestPending;
	TPositionInfo refPosInfo;
	TPositionInfo transPosInfo;
	iTransmitter.SetTransmitOptions(options);
	iTransmitter.TransmitPosition(KThirdParty, KPriority, refPosStatus, refPosInfo, transPosStatus, transPosInfo);
	
	// RequestTransmitLocation()
	TESTL(iProxy->WaitForResponse(KTimeOut) == ENetMsgRequestTransmitLocation);
	TBufC16<14> thirdParty(KThirdParty);
	TPtr16 ptr = thirdParty.Des(); 
	HBufC16* getThirdParty = NULL;
	TLbsNetSessionId* getSessionId = NULL;
	TInt getPriority(0);
	cleanupCnt = iProxy->GetArgsLC(ENetMsgRequestTransmitLocation, &getSessionId, &getThirdParty, &getPriority); 
	TESTL(ptr.Compare(*getThirdParty)==KErrNone);	
	TESTL(getPriority == KPriority);
	iSessionId = *getSessionId; //session ID is initialised by LBS
	CleanupStack::PopAndDestroy(cleanupCnt);

	// ProcessStatusUpdate()
	MLbsNetworkProtocolObserver::TLbsNetProtocolService service = MLbsNetworkProtocolObserver::EServiceTransmitThirdParty;		
	iProxy->CallL(ENetMsgProcessStatusUpdate, &service);
//End Initiate

//Reference Position Notification Start	
	// ProcessLocationUpdate()
	refPosInfo = ArgUtils::ReferencePositionInfo();
	iProxy->CallL(ENetMsgProcessLocationUpdate, &iSessionId, &refPosInfo);
//Reference Position Notification End

	
//Assistance Data Notification Start
	// ProcessAssistanceData()
	TLbsAsistanceDataGroup dataRequestMask = EAssistanceDataReferenceTime;
	RLbsAssistanceDataBuilderSet assistanceData;
	ArgUtils::PopulateLC(assistanceData);
	TInt reason = KErrNone;
	iProxy->CallL(ENetMsgProcessAssistanceData, &dataRequestMask, &assistanceData, &reason);
	CleanupStack::PopAndDestroy(1); //assistanceData
// Assistance Data Notification End
	
// Network Location Request Start
	// ProcessLocationRequest()
	const TBool emergency(EFalse);
	TLbsNetPosRequestQuality quality = ArgUtils::QualityAlpha2(); 
	TLbsNetPosRequestMethod method   = ArgUtils::RequestHybridMethod();	
	iProxy->CallL(ENetMsgProcessLocationRequest, &iSessionId, &emergency, &service, &quality, &method);
// Network Location Request Stop

	//Start the timer
	TTime timerStart;
	timerStart.HomeTime();
	
	// RequestAssistanceData(0)
	TESTL(iProxy->WaitForResponse(KSmallTimeOut) == ENetMsgRequestAssistanceData); 
	TLbsAsistanceDataGroup dataGroup;
	cleanupCnt = iProxy->GetArgsLC(ENetMsgRequestAssistanceData, &dataGroup);
	TESTL(dataGroup == EAssistanceDataNone);
	CleanupStack::PopAndDestroy(cleanupCnt);

	// now wait for either to complete - but we will expect only the asynchrous request
	// waiting for the REF position to complete with KErrNone
	User::WaitForRequest(refPosStatus, transPosStatus); 
	TESTL(refPosStatus==KErrNone);
	TESTL(transPosStatus.Int() == KRequestPending);
	
	//Find the time elapsed from timer
	TTimeIntervalMicroSeconds microseconds;
 	TTime timerStop;
 	timerStop.HomeTime();
 	microseconds = timerStop.MicroSecondsFrom(timerStart); 
	TInt64 timeElapsed = microseconds.Int64();
						
/*** NRH's Alpha2 timer expires. We enter Hybrid mode.***/
	//Test that we do not get response before alpha2 has expired
	TESTL(iProxy->WaitForResponse(KAlpha2Timeout-timeElapsed-KDelta) == ENetMsgTimeoutExpired); 
	TESTL(iProxy->WaitForResponse(2*KDelta) == ENetMsgRespondLocationRequest); 	
	getSessionId = NULL;
	TInt getReason = KErrNone;
	TPositionSatelliteInfo* getPositionInfo = NULL;
	cleanupCnt = iProxy->GetArgsLC(ENetMsgRespondLocationRequest, &getSessionId, &getReason, &getPositionInfo);
	TESTL(getSessionId->SessionNum() == iSessionId.SessionNum());
	TESTL(getReason==KErrNone);
	CleanupStack::PopAndDestroy(cleanupCnt);

	// no need for looping, we assume that the next update location from GPS will give accurate fix
	quality = ArgUtils::Quality(); 
	iProxy->CallL(ENetMsgProcessLocationRequest, &iSessionId, &emergency, &service, &quality, &method);

	// RequestAssistanceData(0)
	TESTL(iProxy->WaitForResponse(KSmallTimeOut) == ENetMsgRequestAssistanceData); 
	cleanupCnt = iProxy->GetArgsLC(ENetMsgRequestAssistanceData, &dataGroup);
	TESTL(dataGroup == EAssistanceDataNone);		
	CleanupStack::PopAndDestroy(cleanupCnt);
	
	//	GPS positions meets required accuracy. This is sent immediately to protocol module
	// The ini file should contain accurate gps fix for this test case to work
	TESTL(iProxy->WaitForResponse(KTTimeout) == ENetMsgRespondLocationRequest);	
	getSessionId = NULL;
	getReason = KErrNone;
	getPositionInfo = NULL;
	cleanupCnt = iProxy->GetArgsLC(ENetMsgRespondLocationRequest, &getSessionId, &getReason, &getPositionInfo);
	TESTL(getSessionId->SessionNum() == iSessionId.SessionNum());
	TESTL(getReason == KErrNone);
	// Test position is the same as in the ini file data fed to the GPS module
	// $update,1,2,51.5015,-0.105,50,2,3*
	TPosition gpsPos;
	getPositionInfo->GetPosition(gpsPos);
	TESTL(gpsPos.Latitude()==51.5015 && gpsPos.Longitude()==-0.105 && gpsPos.Altitude()==50 && gpsPos.HorizontalAccuracy()==2 && gpsPos.VerticalAccuracy()==3); 
	CleanupStack::PopAndDestroy(cleanupCnt);
				
// Network Result Notification Start
	// ProcessLocationUpdate()
	//Final Network Position is the GPS position
	TPositionInfo gpsPosInfo;
	gpsPosInfo.SetPosition(gpsPos);
	gpsPosInfo.SetUpdateType(EPositionUpdateGeneral);
	gpsPosInfo.SetPositionMode(TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted);
	gpsPosInfo.SetPositionModeReason(EPositionModeReasonNone);
	iProxy->CallL(ENetMsgProcessLocationUpdate, &iSessionId, &gpsPosInfo);
// Network Result Notification Stop
	
// Session Complete Start
	reason = KErrNone;
	iProxy->CallL(ENetMsgProcessSessionComplete, &iSessionId, &reason);
	MLbsNetworkProtocolObserver::TLbsNetProtocolServiceMask activeServiceMask = MLbsNetworkProtocolObserver::EServiceNone;
	iProxy->CallL(ENetMsgProcessStatusUpdate, &activeServiceMask);
// Session Complete Stop

	// the REF position request has completed, so now, after injecting the FNP and Session Complete
	// we expect that the other request to complete with KErrNone
	User::WaitForRequest(transPosStatus);
 
	TESTL(transPosStatus==KErrNone);
	return TestStepResult();
	}