void CT_LbsMolrResetAssistance::OnNotifyPositionUpdate(TInt32 aErr, const TPositionInfoBase& aPosInfo) { INFO_PRINTF2(_L("CT_LbsMolrResetAssistance::OnNotifyPositionUpdate() >> NPUD() complete with %d"), aErr); if(iGPSModeNotSupported) { TEST(aErr == KErrNotSupported); } else { // Verify error. TEST(aErr == KErrNone); // Verify position. // Expecting ref pos. if (iState == EInitializing) { iState = ERefLocReceived; TEST(aPosInfo.PositionClassType() == EPositionInfoClass); TEST(aPosInfo.PositionMode() == TPositionModuleInfo::ETechnologyNetwork); // check for refpos details const TPositionInfo posInfo = static_cast<const TPositionInfo&>(aPosInfo); TEST(ArgUtils::ComparePositionInfoToMolrRefPos(posInfo)); } // Expecting gps pos. else if (iState == ERefLocReceived) { iState = EGpsLocReceived; TEST(aPosInfo.PositionClassType() == EPositionInfoClass); if(iPlannedPositionOriginator == EPositionOriginatorModule) { TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyTerminal | TPositionModuleInfo::ETechnologyAssisted)); } if(iPlannedPositionOriginator == EPositionOriginatorNetwork) { TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)); } } // Not expecting anything else. else { INFO_PRINTF1(_L("CT_LbsMolrResetAssistance::OnNotifyPositionUpdate() - FAILED: unexpected state")); TEST(EFalse); } } ReturnToTestStep(); }
void CT_LbsATAEarlyComplete::OnNotifyPositionUpdate(TInt32 aErr, const TPositionInfoBase& aPosInfo) { // Verify position. if (iState == EInitializing) { INFO_PRINTF2(_L("OnNotifyPositionUpdate, Expecting KPositionQualityLoss and got err %d."), aErr); TEST(aErr == KPositionQualityLoss); TInt testCaseId; if (GetIntFromConfig(ConfigSection(), KTestCaseId, testCaseId)) { T_LbsUtils utils; TPositionInfo networkPosInfo = ArgUtils::MolrNetworkPositionInfo(); TEST(utils.Compare_PosInfo(aPosInfo, networkPosInfo)); TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)); TEST(aPosInfo.PositionClassType() == EPositionInfoClass); TEST(aPosInfo.ModuleId() == TUid::Uid(0x10281D43)); // id of NetLocManager } iState = EGotCompleteRequestPosition; } else if (iState == EGotCompleteRequestPosition) { TEST(aErr == KPositionEarlyComplete); T_LbsUtils utils; TPositionInfo networkPosInfo = ArgUtils::MolrNetworkPositionInfo(); TEST(utils.Compare_PosInfo(aPosInfo, networkPosInfo)); TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)); TEST(aPosInfo.PositionClassType() == EPositionInfoClass); TEST(aPosInfo.ModuleId() == TUid::Uid(0x10281D43)); // id of NetLocManager iState = EDone; } else if (iState == EDone) { // not used } else { TEST(EFalse); } ReturnToTestStep(); }
void CT_LbsX3PIntByMoLr::OnNotifyPositionUpdate(TInt32 aErr, const TPositionInfoBase& aPosInfo) { // Verify error. TEST(aErr == KErrNone); // Verify position. TEST(aPosInfo.PositionClassType() == EPositionInfoClass); // Expecting ref pos. if (iState == EInitializing) { iState = ERefLocReceived; TEST(aPosInfo.PositionMode() == TPositionModuleInfo::ETechnologyNetwork); } // Expecting network pos. else if (iState == ERefLocReceived) { iState = EGpsLocReceived; TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyTerminal | TPositionModuleInfo::ETechnologyAssisted)); } // Not expecting anything else. else { TEST(EFalse); } ReturnToTestStep(); }
// // Location Response Message to PSY // EXPORT_C TLbsCellLocationResponseMsg::TLbsCellLocationResponseMsg(const TLbsNetSessionIdInt& aSessionId, TInt aReason, const TPositionInfoBase& aPosInfo): TLbsNetInternalMsgBase(ECellLocationResponse, sizeof(TLbsCellLocationResponseMsg), aSessionId) { // Must make sure that the data to be stored is not bigger than the buffer. __ASSERT_COMPILE(sizeof(TLbsCellLocationResponseMsg) <= KMaximumMessageSizeBytes); iReason = aReason; // Check that the type of aPosInfo is valid TUint32 type = aPosInfo.PositionClassType(); if (((type & EPositionInfoUnknownClass) != EPositionInfoUnknownClass) && ((type & EPositionInfoClass) != EPositionInfoClass) && ((type & EPositionCourseInfoClass) != EPositionCourseInfoClass) && ((type & EPositionSatelliteInfoClass) != EPositionSatelliteInfoClass) && ((type & EPositionExtendedSatelliteInfoClass) != EPositionExtendedSatelliteInfoClass)) { User::Panic(_L("LbsNetInternal"), 1); } // The TPositionInfoBase is just the base class, so we need to copy over // the data from the actual concrete class type. __ASSERT_DEBUG(aPosInfo.PositionClassSize() <= sizeof(TPositionExtendedSatelliteInfo), User::Invariant()); Mem::Copy(&iPosInfo, &aPosInfo, aPosInfo.PositionClassSize()); }
void CLcfPsyDummy1::GetPositionInfoL(TPositionInfoBase& aPosInfo) { // check that requested class is supported if (aPosInfo.PositionClassType() & ~(EPositionInfoClass| EPositionGenericInfoClass)) { // some more bits are set User::RequestComplete(iStatusPtr, KErrArgument); return; } // PSY Tester bug fix: First of all clear HPositionGenericInfo fields, // if the parameter was of type HPositionGenericInfo if (aPosInfo.PositionClassType() & EPositionGenericInfoClass) // was EPositionClassInfo { HPositionGenericInfo* posInfo = static_cast<HPositionGenericInfo*>(&aPosInfo); // Clear old data posInfo->ClearPositionData(); } // Check which position information has been requested // and provide that information. if (aPosInfo.PositionClassType() & EPositionInfoClass) // was EPositionClassInfo { GetBasicPositionInfoL(aPosInfo); } if (aPosInfo.PositionClassType() & EPositionGenericInfoClass) // was EPositionClassInfo { GetGenericPositionInfoL(aPosInfo); } // Complete the request User::RequestComplete(iStatusPtr, KErrNone); }
void CLcfPsyDummy3::GetPositionInfoL(TPositionInfoBase& aPosInfo) { // check that requested class is supported if (aPosInfo.PositionClassType() & ~(EPositionInfoClass| EPositionGenericInfoClass| EPositionCourseInfoClass| EPositionSatelliteInfoClass)) { // some more bits are set User::RequestComplete(iStatusPtr, KErrArgument); return; } // Check which position information has been requested // and provide that information. if (aPosInfo.PositionClassType() & EPositionInfoClass) // was EPositionClassInfo { GetBasicPositionInfoL(aPosInfo); } if (aPosInfo.PositionClassType() & EPositionGenericInfoClass) // was EPositionClassInfo { GetGenericPositionInfoL(aPosInfo); } if (aPosInfo.PositionClassType() & EPositionCourseInfoClass) // was EPositionClassInfo { GetPositionCourseInfoL(aPosInfo); } if (aPosInfo.PositionClassType() & EPositionSatelliteInfoClass) // was EPositionClassInfo { GetPositionSatelliteInfoL(aPosInfo); } // Complete the request User::RequestComplete(iStatusPtr, KErrNone); }
EXPORT_C TInt RLbsNetworkPositionUpdates::GetPositionInfo(TLbsNetSessionIdInt& aSessionId, TPositionInfoBase& aPosInfo, TTime& aTargetTime, TTime& aActualTime) { __ASSERT_DEBUG(iNetworkPositionProperty.Handle()!=NULL, User::Invariant()); //Check that aPosInfo is either TPositionInfo, TPositionCourseInfo, TPositionSatelliteInfo or TPositionExtendedSatelliteInfo. const TUint32 classType = aPosInfo.PositionClassType(); const TUint classSize = aPosInfo.PositionClassSize(); if (!IsValidPositionInfoBaseType(classType, classSize)) { return KErrNotSupported; } TLbsPositionUpdateData data; TLbsPositionUpdateDataPckg pckg(data); TInt err = iNetworkPositionProperty.Get(pckg); if(err!=KErrNone) { return err; } // is the data contained valid? if(data.iValidData==EFalse) { return KErrNotReady; } aTargetTime = data.iTargetTime; aActualTime = data.iActualTime; aSessionId = data.iSessionId; // copy the postion types, this preserves the type and size of the // to type, so the copy is offset from the base addresses of the // structs. NB this relies on standard C++ class ram layout i.e. address of the // parent class property is always lower than the child class. TUint8* startCopyToAddress = reinterpret_cast<TUint8*>(&aPosInfo)+sizeof(TPositionClassTypeBase); const TUint8* const startCopyFromAddress = reinterpret_cast<TUint8*>(&data.iSatInfo)+sizeof(TPositionClassTypeBase); // NB in the future is could be very dodgy, 'cos it always assumes that the // strct we copy to has a TSatInfoClass in it and that this is always // the biggest possible derative of a TPosInfoBase class const TInt numberOfBytesToCopy = classSize-sizeof(TPositionClassTypeBase); TUint8* endAddr = Mem::Copy(startCopyToAddress, startCopyFromAddress, numberOfBytesToCopy); // sanity check and return any error code if(endAddr != startCopyToAddress + numberOfBytesToCopy) { return KErrGeneral; } else { return err; } }
void CT_LbsHybridUEAssistedMOLRNoGPSUpdate::OnNotifyPositionUpdate(TInt32 aErr, const TPositionInfoBase& aPosInfo) { INFO_PRINTF1(_L("RunL() - OnNotifyPositionUpdate()")); // Verify position. TEST(aPosInfo.PositionClassType() == EPositionInfoClass); // Expecting ref pos. if (iState == EInitializing) { // Verify error. TEST(aErr == KErrNone); iState = ERefLocReceived; TEST(aPosInfo.PositionMode() == TPositionModuleInfo::ETechnologyNetwork); INFO_PRINTF1(_L("RunL() - Got ref location")); } else { // expecting a position but not of the requitred quality INFO_PRINTF2(_L("RunL() - second %d"), aErr); if(iExpectedApiBehaviour == EApiVariant2) { // for variant 2 behaviour TEST(aErr == KErrTimedOut); } else { TEST(aErr == KPositionQualityLoss); } TEST(ETrue); } ReturnToTestStep(); }
EXPORT_C TInt RLbsNetworkPositionUpdates::SetPositionInfo(const TLbsNetSessionIdInt& aSessionId, const TInt& aError, const TPositionInfoBase& aPositionInfo, const TTime& aActualTime) { __ASSERT_DEBUG(iNetworkPositionProperty.Handle()!=NULL, User::Invariant()); //Check that aPosInfo is either TPositionInfo, TPositionCourseInfo, or TPositionSatelliteInfo. const TUint32 classType = aPositionInfo.PositionClassType(); const TUint classSize = aPositionInfo.PositionClassSize(); if (!IsValidPositionInfoBaseType(classType, classSize)) { return KErrNotSupported; } TLbsPositionUpdateData data; data.iError = aError; data.iTargetTime = 0; data.iActualTime = aActualTime; data.iSessionId = aSessionId; // indicate that the property is ok, and now contains no data. data.iValidData = ETrue; // Copy the full class type, size and data from aPositionInfo into the property. // This will set the type of the object in the property to the type being passed in. TUint8* startCopyToAddress = reinterpret_cast<TUint8*>(&data.iSatInfo); const TUint8* const startCopyFromAddress = reinterpret_cast<const TUint8*>(&aPositionInfo); const TInt numberOfBytesToCopy = aPositionInfo.PositionClassSize(); TUint8* endAddr = Mem::Copy(startCopyToAddress, startCopyFromAddress, numberOfBytesToCopy); // sanity check and return any error code if(endAddr != (startCopyToAddress + numberOfBytesToCopy)) { return KErrGeneral; } TLbsPositionUpdateDataPckgC pckg(data); TInt err = iNetworkPositionProperty.Set(pckg); return err; }
void CT_LbsPTAMOLRPartialEarlyComplete::OnNotifyPositionUpdate(TInt32 aErr, const TPositionInfoBase& aPosInfo) { // Verify position. TEST(aPosInfo.PositionClassType() == EPositionInfoClass); // Expecting first partial update, NaN position. if (iState == EInitializing) { iState = EGpsPartialInitReceived; TEST(aErr == KPositionPartialUpdate); TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyTerminal | TPositionModuleInfo::ETechnologyAssisted)); // check for nan in partial updates const TPositionInfo posInfo = static_cast<const TPositionInfo&>(aPosInfo); TESTL(ArgUtils::ComparePositionInfoToNan(posInfo)); } // Expecting previous partial update due to CompleteRequest(...) else if (iState == EGpsPartialInitReceived) { iState = EGpsPartialEarlyReceived; TEST(aErr == KPositionEarlyComplete); TEST(aPosInfo.PositionMode() == (TPositionModuleInfo::ETechnologyTerminal | TPositionModuleInfo::ETechnologyAssisted)); const TPositionInfo posInfo = static_cast<const TPositionInfo&>(aPosInfo); TESTL(ArgUtils::ComparePositionInfoToNan(posInfo)); } // Not expecting anything else. else { TEST(EFalse); } ReturnToTestStep(); }
void CNetworkPsy2::NotifyPositionUpdate( TPositionInfoBase& aPosInfo, TRequestStatus& aStatus) { iRequestStatus = &aStatus; iPositionInfoBase = &aPosInfo; if(aPosInfo.PositionClassType() & EPositionGenericInfoClass) { //Check if this is confiuration request HPositionGenericInfo* genInfo = static_cast<HPositionGenericInfo*>(&aPosInfo); if(genInfo->IsRequestedField(KIntGpsPsy1ConfigItemsNumber)) { //Config PSY TRAPD(err, ConfigPsyL(*genInfo)); CompleteRequest(err); StartTimerIfNeeded(); return; } } StartTimerIfNeeded(); }
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; }
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); } } }