/** 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); } } } } }
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); } } } }
// --------------------------------------------------------- // 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); } }