diff -r 000000000000 -r 9cfd9a3ee49c datasourcemodules/simulationpositioningmodule/src/EPos_TNmeaSentenceParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datasourcemodules/simulationpositioningmodule/src/EPos_TNmeaSentenceParser.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,956 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + + +// INCLUDE FILES +#include "EPos_TNmeaSentenceParser.h" + +// CONSTANTS +const signed int KCoordTokenS = 'S'; +const signed int KCoordTokenW = 'W'; +const signed int KCoordTokenDot = '.'; + +const TReal32 KPosUERE = 10.0; + +const TNmeaSentence KPosUnknownSentence = 0; +const TNmeaSentence KPosGGASentence = ('G'<<16) + ('G'<<8) + 'A'; +const TNmeaSentence KPosGSASentence = ('G'<<16) + ('S'<<8) + 'A'; +const TNmeaSentence KPosGSVSentence = ('G'<<16) + ('S'<<8) + 'V'; +const TNmeaSentence KPosRMCSentence = ('R'<<16) + ('M'<<8) + 'C'; +const TNmeaSentence KPosGLLSentence = ('G'<<16) + ('L'<<8) + 'L'; + +// PGRMM - propriatary GARMIN sentence +const TNmeaSentence KPosPGRMMSentence = ('G'<<24) + ('R'<<16) + ('M'<<8) + 'M'; + +const TInt KPosMinSentenceLength = 7; +const TUint KPosNMEASentenceStartToken = '$'; +const TInt KPosNofSatelliteSlotsInGSA = 12; + +const TReal32 KKnotsToMetrePerSecFactor = 1.852F / 3.6F; + +const TInt KMaxSatellitesPerSentence = 4; + +// ================= MEMBER FUNCTIONS ======================= + +TNmeaSentenceParser::TNmeaSentenceParser() : + iProgress(KPosNotParsed), + iGSVIndex(1), + iNumNmeaSentences(0) + { + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParseSentenceL +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParseSentence( + const TDesC8& aSentence, + TPositionInfo& aPosInfo, TBool aConst) + { + if (aSentence.Length() == 0 || + !(aSentence[0] == KPosNMEASentenceStartToken) || + !VerifyChecksum(aSentence)) + { + // Return KPosErrorNotValidNMEASentence since this + // sentence won't be set as parsed + // and therefore PSY should make another try to get a full fix. + return KPosErrorNotValidNMEASentence; + } + + TNmeaSentence type = SentenceType(aSentence); + + // Do not permit duplicate sentences of the types GLL, GGA, GSA and RMC + if(!aConst) + { + if (type == KPosGLLSentence && (iProgress & KPosGLLParsed) || + type == KPosGGASentence && (iProgress & KPosGGAParsed) || + type == KPosGSASentence && (iProgress & KPosGSAParsed) || + type == KPosRMCSentence && (iProgress & KPosRMCParsed)) + { + return KPosErrorAlreadyParsed; + } + } + + if (aPosInfo.PositionClassType() & EPositionGenericInfoClass) + { + // Store raw NMEA sentence in position info + HPositionGenericInfo& genInfo = + static_cast (aPosInfo); + AddNmeaSentence(genInfo, aSentence); + } + + switch (type) + { + case KPosGLLSentence: + iProgress |= KPosGLLParsed; + return KErrNone; + case KPosGGASentence: + return ParseGGA(aSentence, aPosInfo); + case KPosRMCSentence: + return ParseRMC(aSentence, aPosInfo); + case KPosGSASentence: + return ParseGSA(aSentence, aPosInfo); + case KPosGSVSentence: + return ParseGSV(aSentence, aPosInfo, aConst); + case KPosPGRMMSentence: + return ParsePGRMM(aSentence, aPosInfo); + default: + return KErrNone; + } + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::Progress +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::Progress() + { + return iProgress; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::Reset +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void TNmeaSentenceParser::Reset() + { + iProgress = KPosNotParsed; + iGSVIndex = 1; + iNumNmeaSentences = 0; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::SentenceType +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TNmeaSentence TNmeaSentenceParser::SentenceType(const TDesC8& aSentence) + { + if (aSentence.Length() <= KPosMinSentenceLength) + { + return KPosUnknownSentence; + } + + TInt type = (aSentence[3]<<16) + (aSentence[4]<<8) + aSentence[5]; + + if (aSentence[1] == 'P') + { + type += (aSentence[2]<<24); + } + + return type; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParseGGA +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParseGGA( + const TDesC8& aSentence, + TPositionInfo& aPositionInfo) + { + TDesTokeniser tokeniser(aSentence); + + tokeniser.SkipToken(2); // Initial token, timestamp + + TPtrC8 latitude = tokeniser.NextToken(); + TPtrC8 dLat = tokeniser.NextToken(); + + TPtrC8 longitude = tokeniser.NextToken(); + TPtrC8 dLong = tokeniser.NextToken(); + + TInt quality = DesToInt(tokeniser.NextToken()); + + if (quality == 0) + { + // Return KPosErrorNotValidNMEASentence since this + // sentence won't be set as parsed + // and therefore PSY should make another try to get a full fix. + return KPosErrorNotValidNMEASentence; + } + + TRealX nan; + nan.SetNaN(); + + // Number of tracked satellites, Horizontal dilution + tokeniser.SkipToken(2); + + TPtrC8 altitudeC = tokeniser.NextToken(); // // Mean-sea altitude + TReal32 altitude = nan; + if (altitudeC.Length() > 0) + { + altitude = DesToFloat(altitudeC); + } + + TReal latCoord = nan; + ToCoordinate(latitude, dLat, latCoord); + TReal longCoord = nan; + ToCoordinate(longitude, dLong, longCoord); + + tokeniser.SkipToken(); // Unit (meters) + + TPtrC8 gsValueC = tokeniser.NextToken(); // Geoidal Separation + TReal32 gsValue = nan; + if (gsValueC.Length() > 0) + { + gsValue = DesToFloat(gsValueC); + } + + TReal32 wgs84alt = nan; + if (!Math::IsNaN(TRealX(altitude)) && !Math::IsNaN(TRealX(gsValue))) + { + // Wgs84-altitude = Mean-sea level altitude + Geoidal separation + wgs84alt = altitude + gsValue; + } + else + { + // If there is no altitude, there should not be a vertical accuracy. + TPosition pos; + aPositionInfo.GetPosition(pos); + pos.SetVerticalAccuracy(nan); + aPositionInfo.SetPosition(pos); + } + + // Set position + TPosition pos; + aPositionInfo.GetPosition(pos); + pos.SetCoordinate(latCoord, longCoord, wgs84alt); + if (!Math::IsNaN(latCoord) || !Math::IsNaN(longCoord)) + { + pos.SetCurrentTime(); + } + aPositionInfo.SetPosition(pos); + + // Check if generic info class + if (aPositionInfo.PositionClassType() & EPositionGenericInfoClass) + { + HPositionGenericInfo& genInfo = + static_cast (aPositionInfo); + TInt err = KErrNone; + if (genInfo.IsRequestedField( + EPositionFieldSatelliteGeoidalSeparation) && + !Math::IsNaN(TRealX(gsValue))) + { + err = genInfo.SetValue(EPositionFieldSatelliteGeoidalSeparation, + gsValue); + } + if (genInfo.IsRequestedField( + EPositionFieldSatelliteSeaLevelAltitude) && + !Math::IsNaN(TRealX(altitude))) + { + err = genInfo.SetValue(EPositionFieldSatelliteSeaLevelAltitude, + altitude); + } + if (err != KErrNone) + { + return err; + } + } + + iProgress |= KPosGGAParsed; + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParseRMC +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParseRMC( + const TDesC8& aSentence, + TPositionInfo& aPositionInfo) + { + // Check if generic, course or satellite info class + if (aPositionInfo.PositionClassType() & (EPositionGenericInfoClass | + EPositionCourseInfoClass | EPositionSatelliteInfoClass)) + { + TDesTokeniser tokeniser(aSentence); + + tokeniser.SkipToken(); // Initial token + + TReal timestamp = DesToReal(tokeniser.NextToken()); // Timestamp + tokeniser.SkipToken(5); // status, latitude * 2, longitude * 2 + + TRealX nan; + nan.SetNaN(); + + TPtrC8 speedC = tokeniser.NextToken(); // Speed + TReal32 speed = nan; + if (speedC.Length() > 0) + { + speed = DesToFloat(speedC); + // Speed is in knots. Transform to metres/sec + speed *= KKnotsToMetrePerSecFactor; + } + + TPtrC8 trueCourseC = tokeniser.NextToken(); // True course + TReal32 trueCourse = nan; + if (trueCourseC.Length() > 0) + { + trueCourse = DesToFloat(trueCourseC); + } + + TInt date = DesToInt(tokeniser.NextToken()); // Date + + TPtrC8 magVarC = tokeniser.NextToken(); // Magnetic variation + TReal32 magVar = nan; + if (magVarC.Length() > 0) + { + magVar = DesToFloat(magVarC); + } + TPtrC8 dirMagVar = tokeniser.NextToken(); // Magnetic direction + TPtrC8 modeIndicator = tokeniser.NextToken('*'); // Mode indicator + + _LIT8(KDataNotValid, "N"); + if (modeIndicator.Compare(KDataNotValid) == 0) + { + return KPosErrorNotValidNMEASentence; + } + + if (dirMagVar.Length() && dirMagVar[0] == 'E' && !Math::IsNaN(TRealX(magVar))) + { + magVar = -magVar; + } + + TInt hours = static_cast (timestamp / 10000); + TInt minutes = (static_cast (timestamp / 100)) % 100; + TInt seconds = (static_cast (timestamp)) % 100; + TInt microSeconds = + ((static_cast (timestamp * 100)) % 100) * 10000; + + const TInt KInitialYear = 2000; + TInt days = (date / 10000) % 100; + TInt months = (date / 100) % 100; + TInt years = date % 100 + KInitialYear; + + if (timestamp < 0 || hours > 23 || minutes > 59 || seconds > 59 || + date < 0 || days < 1 || days > 31 || months < 1 || + months > 12 || years > 2099) + { + return KErrCorrupt; + } + + TDateTime time = TDateTime + (years, static_cast (months - 1), days, hours, minutes, + seconds, microSeconds); + + // Check if generic info class + if (aPositionInfo.PositionClassType() & EPositionGenericInfoClass) + { + HPositionGenericInfo& genInfo = + static_cast (aPositionInfo); + TInt err = KErrNone; + if (genInfo.IsRequestedField(EPositionFieldTrueCourse) && + !Math::IsNaN(TRealX(trueCourse))) + { + err = genInfo.SetValue(EPositionFieldTrueCourse, trueCourse); + } + if (genInfo.IsRequestedField(EPositionFieldHorizontalSpeed) && + !Math::IsNaN(TRealX(speed))) + { + err = genInfo.SetValue(EPositionFieldHorizontalSpeed, speed); + } + if (genInfo.IsRequestedField(EPositionFieldMagneticCourse) && + !Math::IsNaN(TRealX(magVar)) && + !Math::IsNaN(TRealX(trueCourse))) + { + err = genInfo.SetValue(EPositionFieldMagneticCourse, + magVar + trueCourse); + } + if (genInfo.IsRequestedField(EPositionFieldSatelliteTime)) + { + err = genInfo.SetValue(EPositionFieldSatelliteTime, + TTime(time)); + } + if (err != KErrNone) + { + return err; + } + } + // course info, sat info + else + { + TPositionCourseInfo& courseInfo = + static_cast (aPositionInfo); + TCourse course; + course.SetHeading(trueCourse); + course.SetSpeed(speed); + courseInfo.SetCourse(course); + // satellite info + if (aPositionInfo.PositionClassType() & + EPositionSatelliteInfoClass) + { + TPositionSatelliteInfo& satInfo = + static_cast (aPositionInfo); + satInfo.SetSatelliteTime(TTime(time)); + } + } + } + iProgress |= KPosRMCParsed; + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParseGSA +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParseGSA( + const TDesC8& aSentence, + TPositionInfo& aPositionInfo) + { + TDesTokeniser tokeniser(aSentence); + + tokeniser.SkipToken(2); // Initial token, Selection + + TInt twoDthreeD = DesToInt(tokeniser.NextToken()); + if (twoDthreeD == 1) + { + // Return KPosErrorNotValidNMEASentence since this + // sentence won't be set as parsed + // and therefore PSY should make another try to get a full fix. + return KPosErrorNotValidNMEASentence; + } + + TInt8 numUsedSatellites = 0; + for (TInt i = 0; i < KPosNofSatelliteSlotsInGSA; i++) + { + // Satelite Id nr used for fix + TPtrC8 satIdNrC = tokeniser.NextToken(); + if (satIdNrC.Length() > 0) + { + // Check if satellite info class + if (aPositionInfo.PositionClassType() & + EPositionSatelliteInfoClass) + { + TPositionSatelliteInfo& satInfo = + static_cast (aPositionInfo); + + TSatelliteData satData; + TInt satIndex = 0; + TInt satId = DesToInt(satIdNrC); + TInt err = GetSatelliteListIndex(satInfo, satId, satIndex); + if (err == KErrNotFound) + { + satData.SetSatelliteId(satId); + satData.SetIsUsed(ETrue); + err = satInfo.AppendSatelliteData(satData); + if (err != KErrNone) + { + return err; + } + } + else // Satellite already exists + { + satInfo.GetSatelliteData(satIndex, satData); + satData.SetIsUsed(ETrue); + err = UpdateSatDataInList(satInfo, satData, satIndex); + if (err != KErrNone) + { + return err; + } + } + } + numUsedSatellites++; + } + } + + TRealX nan; + nan.SetNaN(); + TPtrC8 pdopC = tokeniser.NextToken(); // PDop + TReal32 pdop = nan; + TPtrC8 hdopC = tokeniser.NextToken(); // HDop + TReal32 hdop = nan; + TPtrC8 vdopC = tokeniser.NextToken('*'); // VDop + TReal32 vdop = nan; + + if (pdopC.Length() > 0) + { + pdop = DesToFloat(pdopC); + } + + if (hdopC.Length() > 0) + { + hdop = DesToFloat(hdopC); + // Set basic info + TPosition pos; + aPositionInfo.GetPosition(pos); + pos.SetHorizontalAccuracy(KPosUERE * hdop); + + // Set vertical accuracy, but only if we have altitude, or if we may get + // altitude in later NMEA sentences. + if (twoDthreeD == 3 && + !((iProgress & KPosGGAParsed) && + Math::IsNaN(TRealX(pos.Altitude())))) + { + pos.SetVerticalAccuracy(1.5f * KPosUERE * hdop); + } + aPositionInfo.SetPosition(pos); + } + + if (vdopC.Length() > 0) + { + vdop = DesToFloat(vdopC); + } + + // Check if generic info class + if (aPositionInfo.PositionClassType() & EPositionGenericInfoClass) + { + HPositionGenericInfo& genInfo = + static_cast (aPositionInfo); + TInt err = KErrNone; + + if (TRealX(pdop).IsNaN() && + !TRealX(vdop).IsNaN() && + !TRealX(hdop).IsNaN()) + { + TReal trg(pdop); + err = Math::Sqrt(trg, TReal(hdop * hdop + vdop * vdop)); + pdop = TReal32(trg); + } + + if (genInfo.IsRequestedField(EPositionFieldSatelliteHorizontalDoP) && + !Math::IsNaN(TRealX(hdop))) + { + err = genInfo.SetValue(EPositionFieldSatelliteHorizontalDoP, hdop); + } + if (genInfo.IsRequestedField(EPositionFieldSatelliteVerticalDoP) && + !Math::IsNaN(TRealX(vdop))) + { + err = genInfo.SetValue(EPositionFieldSatelliteVerticalDoP, vdop); + } + if (genInfo.IsRequestedField(EPositionFieldSatellitePositionDoP) && + !Math::IsNaN(TRealX(pdop))) + { + err = genInfo.SetValue(EPositionFieldSatellitePositionDoP, pdop); + } + if (genInfo.IsRequestedField(EPositionFieldSatelliteNumUsed)) + { + err = genInfo.SetValue(EPositionFieldSatelliteNumUsed, + numUsedSatellites); + } + if (err != KErrNone) + { + return err; + } + } + // satellite info + else if (aPositionInfo.PositionClassType() & EPositionSatelliteInfoClass) + { + TPositionSatelliteInfo& satInfo = + static_cast (aPositionInfo); + satInfo.SetHorizontalDoP(hdop); + satInfo.SetVerticalDoP(vdop); + } + + iProgress |= KPosGSAParsed; + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParseGSV +// +// Must be called in sequence for each GSV sentence +// otherwise an error code will be returned. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParseGSV( + const TDesC8& aSentence, + TPositionInfo& aPositionInfo, + TBool aConst) + { + TDesTokeniser tokeniser(aSentence); + + tokeniser.SkipToken(2); // Initial token, Number of sentences + + TInt sentenceIndex = DesToInt(tokeniser.NextToken()); // Message number + + // OK to try to parse a sentence with the wrong index, but progress + // will not be updated. + // + // Because iGSVIndex is incremented each time function is called with aConst = EFalse + // then to get same result like for previous read we have to temporary decrement + // this value. Then if aConst is ETrue we are decrementing iGSVIndex + TInt tempGSVIndex = iGSVIndex; + if(aConst) + { + tempGSVIndex--; + } + if (sentenceIndex != tempGSVIndex) + { + iGSVIndex = 1; + return KErrNone; + } + if(!aConst) + { + iGSVIndex++; + } + + // Number of satellites in view + TInt8 satInView = static_cast (DesToInt(tokeniser.NextToken())); + + // Check if generic info class + if (aPositionInfo.PositionClassType() & EPositionGenericInfoClass) + { + HPositionGenericInfo& genInfo = + static_cast (aPositionInfo); + TInt err = KErrNone; + if (genInfo.IsRequestedField(EPositionFieldSatelliteNumInView)) + { + err = genInfo.SetValue(EPositionFieldSatelliteNumInView, + satInView); + if (err != KErrNone) + { + return err; + } + } + } + // satellite info + else if (aPositionInfo.PositionClassType() & EPositionSatelliteInfoClass) + { + TPositionSatelliteInfo& satInfo = + static_cast (aPositionInfo); + + for (TInt n = 0; n < KMaxSatellitesPerSentence; n++) + { + TPtrC8 prnPtrC = tokeniser.NextToken(); // PRN + TPtrC8 elevationPtrC = tokeniser.NextToken(); // Elevation + TPtrC8 azimuthPtrC = tokeniser.NextToken(); // Azimuth + + if (prnPtrC.Length() > 0) + { + TPtrC8 signalStrengtPtrC; + // Last satellite in sentence + if (n == (KMaxSatellitesPerSentence - 1)) + { + signalStrengtPtrC.Set(tokeniser.NextToken('*')); // SNR + } + else + { + signalStrengtPtrC.Set(tokeniser.NextToken()); // SNR + } + + TSatelliteData satSata; + TInt satIndex; + TInt satId = DesToInt(prnPtrC); + TInt err = GetSatelliteListIndex(satInfo, satId, satIndex); + if (err == KErrNotFound) + { + satSata.SetSatelliteId(satId); + if (elevationPtrC.Length() > 0) + { + satSata.SetElevation(DesToFloat(elevationPtrC)); + } + if (azimuthPtrC.Length() > 0) + { + satSata.SetAzimuth(DesToFloat(azimuthPtrC)); + } + if (signalStrengtPtrC.Length() > 0) + { + satSata.SetSignalStrength(DesToInt(signalStrengtPtrC)); + } + err = satInfo.AppendSatelliteData(satSata); + if (err != KErrNone) + { + return err; + } + } + else // Satellite already exists + { + satInfo.GetSatelliteData(satIndex, satSata); + satSata.SetSatelliteId(DesToInt(prnPtrC)); + if (elevationPtrC.Length() > 0) + { + satSata.SetElevation(DesToFloat(elevationPtrC)); + } + if (azimuthPtrC.Length() > 0) + { + satSata.SetAzimuth(DesToFloat(azimuthPtrC)); + } + if (signalStrengtPtrC.Length() > 0) + { + satSata.SetSignalStrength(DesToInt(signalStrengtPtrC)); + } + err = UpdateSatDataInList(satInfo, satSata, satIndex); + if (err != KErrNone) + { + return err; + } + } + } + } + } + + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ParsePGRMM +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::ParsePGRMM( + const TDesC8& aSentence, + TPositionInfo& /*aPositionInfo*/) + { + _LIT8(KWgs84, "WGS 84"); + TDesTokeniser tokeniser(aSentence); + + tokeniser.SkipToken(); // initial token + + TPtrC8 datum = tokeniser.NextToken('*'); + if (datum.Compare(KWgs84) != 0) + { + return KErrNotSupported; + } + + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::AddNmeaSentence +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::AddNmeaSentence( + HPositionGenericInfo& aPositionGenericInfo, + const TDesC8& aSentence, TBool aConst) + { + TInt err = KErrNone; + + // Check if NMEA data is requested + if (aPositionGenericInfo.IsRequestedField(EPositionFieldNMEASentences)) + { + TUint16 sentenceNumber = + static_cast (EPositionFieldNMEASentencesStart + + iNumNmeaSentences); + err = aPositionGenericInfo.SetValue(sentenceNumber, aSentence); + if(!aConst) + ++iNumNmeaSentences; + TUint8 sentences = static_cast (iNumNmeaSentences); + err = aPositionGenericInfo.SetValue(EPositionFieldNMEASentences, + sentences); + } + return err; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::ToCoordinate +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void TNmeaSentenceParser::ToCoordinate( + const TDesC8& aDes, + const TDesC8& aDir, + TReal& aCoordinate) + { + const TInt KPosMinutesIntegerLength = 2; + const TReal KPosMinutesPerDegree = 60.0; + + TInt point = aDes.Locate(KCoordTokenDot); + + if (point >= KPosMinutesIntegerLength) + { + TInt deg = DesToInt(aDes.Left(point - KPosMinutesIntegerLength)); + TReal min = DesToReal(aDes.Mid(point - KPosMinutesIntegerLength)); + aCoordinate = TReal(deg) + min / KPosMinutesPerDegree; + + if (aDir.Length() && (aDir[0] == KCoordTokenS || aDir[0] == KCoordTokenW)) + { + aCoordinate = - aCoordinate; + } + } + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::DesToInt +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::DesToInt(const TPtrC8& aDes) + { + TLex8 lexer(aDes); + TInt integer; + + lexer.Val(integer); + return integer; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::DesToFloat +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TReal32 TNmeaSentenceParser::DesToFloat(const TPtrC8& aDes) + { + TLex8 lexer(aDes); + TReal32 floatNumber; + + lexer.Val(floatNumber, TChar(KCoordTokenDot)); + return floatNumber; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::DesToReal +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TReal TNmeaSentenceParser::DesToReal(const TPtrC8& aDes) + { + TLex8 lexer(aDes); + TReal realNumber; + + lexer.Val(realNumber, TChar('.')); + return realNumber; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::VerifyChecksum +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TBool TNmeaSentenceParser::VerifyChecksum(const TDesC8& aSentence) + { + TUint8 checksum = 0; + TInt i; + for (i = 1; i < aSentence.Length() && aSentence[i] != '*'; i++) + { + checksum ^= aSentence[i]; + } + + if (++i + 1 < aSentence.Length()) + { + TUint8 sum = TUint8((CharToNibble(aSentence[i]) << 4) + + CharToNibble(aSentence[i+1])); + if (sum == checksum) + { + return ETrue; + } + } + + return EFalse; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::CharToNibble +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TUint8 TNmeaSentenceParser::CharToNibble(const TUint8 aChar) + { + if (aChar <= '9') + { + return TUint8(aChar - '0'); + } + else + { + return TUint8(aChar - 'A' + 10); + } + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::GetSatelliteListIndex +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::GetSatelliteListIndex( + const TPositionSatelliteInfo& aSatInfo, + TInt aPrnNumber, + TInt& aIndex) + { + TSatelliteData satData; + + for (TInt i = 0; i < aSatInfo.NumSatellitesInView(); i++) + { + aSatInfo.GetSatelliteData(i, satData); + if (satData.SatelliteId() == aPrnNumber) + { + aIndex = i; + return KErrNone; + } + } + return KErrNotFound; + } + +// ---------------------------------------------------------------------------- +// TNmeaSentenceParser::UpdateSatDataInList +// +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt TNmeaSentenceParser::UpdateSatDataInList( + TPositionSatelliteInfo& aSatInfo, + TSatelliteData aSatData, + TInt aIndex) + { + TInt nrOfSat = aSatInfo.NumSatellitesInView(); + RArray satList; + TInt i; + TInt err; + for (i = 0; i < nrOfSat; i++) + { + TSatelliteData satData; + aSatInfo.GetSatelliteData(i,satData); + err = satList.Append(satData); + if (err != KErrNone) + { + satList.Close(); + return err; + } + } + + if (aIndex < nrOfSat) + { + satList[aIndex] = aSatData; + } + + // Re-create satellite list in SatelliteInfo + aSatInfo.ClearSatellitesInView(); + for (i = 0; i < satList.Count(); i++) + { + err = aSatInfo.AppendSatelliteData(satList[i]); + if (err != KErrNone) + { + satList.Close(); + return err; + } + } + satList.Close(); + return KErrNone; + } + +// End of File