diff -r a2efdd544abf -r b47902b73a93 datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/Nmea/BTGPSNmeaParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/Nmea/BTGPSNmeaParser.cpp Fri Jun 04 10:34:15 2010 +0100 @@ -0,0 +1,416 @@ +// Copyright (c) 2004-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 + +#include "BTGPSNmeaParser.h" +#include "BTGPSMessageDef.h" +#include "BTGPSPanic.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +//NMEA sentence field delimiter +const TUint8 KNmeaFieldDelimiter = ','; + +//NMEA sentecne checksum delimiter +const TUint8 KNmeaChecksumDelimiter = '*'; + +//Data start postion of NMEA sentence +const TInt KNmeaDataStartPos = 1; + +//Minimum length of NMEA sentence(starter and check sum) +const TInt KNmeaMininumLength = 4; + +//Checksum field length +const TInt KNmeaChecksumFieldLength = 2; + +//Maximum length of address field length +const TInt KNmeaMaxAddressFieldLength = 32; + +//Decimal seperator +const TUint8 KDecimalSeperator = '.'; + +/** +* Structure for address field Id map +*/ +struct TAddressFieldMessageIdMap + { + TText8 iField[KNmeaMaxAddressFieldLength]; //Field text + TInt iId; //Field id + }; + +/** +* NMEA and Sirf specific NMEA sentence sId field text and +* id mapping defination +*/ +const struct TAddressFieldMessageIdMap KNmeaAddressIdMap[]= + { + {"GPGSV", ENmeaGPGSV}, + {"GPGLL", ENmeaGPGLL}, + {"GPRMC", ENmeaGPRMC}, + {"GPVTG", ENmeaGPVTG}, + {"GPGGA", ENmeaGPGGA}, + {"GPGSA", ENmeaGPGSA}, + {"PSRF107", ENmeaPSRF107}, + {"PSRF103", ENmeaPSRF103}, + {"PSRF101", ENmeaPSRF101}, + {"PSRF105", ENmeaPSRF105}, + {"PSRF201", ENmeaPSRF201}, + {"PNOK", ENmeaProprietaryNok} + }; + +/** +* PNOK message id field text and id mapping defination +*/ +const struct TAddressFieldMessageIdMap KNmeaPNokAddressIdMap[]= + { + {"OK", ENmeaPNokOk}, + {"RESET", ENmeaPNokReset}, + {"MSGS", ENmeaPNokPeriodicMsgs}, + {"LOWPWR", ENmeaPNokLowPwrMode}, + {"NIGHTMODE", ENmeaPNokNightMode}, + {"VER", ENmeaPNokVersionInfo}, + {"STAT", ENmeaPNokPeriodicEvents}, + {"TIME", ENmeaPNokReferenceTime} + }; + + + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::TBTGPSNmeaParser +// ----------------------------------------------------------------------------- +TBTGPSNmeaParser::TBTGPSNmeaParser() : TDelimitedParserBase8() + { + SetDelimiter(KNmeaFieldDelimiter); + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::SetNmeaSentence +// ----------------------------------------------------------------------------- +void TBTGPSNmeaParser::SetNmeaSentence(const TDesC8& aNmea) + { + iNmea.Set(aNmea); + iId = ENmeaNull; + if(CheckValidity()) + { + Parse(TrimSentence()); + GetMessageId(); + } + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::NmeaSentence +// ----------------------------------------------------------------------------- +const TDesC8& TBTGPSNmeaParser::NmeaSentence() const + { + return iNmea; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::IsValid +// ----------------------------------------------------------------------------- +TBool TBTGPSNmeaParser::IsValid() const + { + return iId!=ENmeaNull; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::MessageId +// ----------------------------------------------------------------------------- +TInt TBTGPSNmeaParser::MessageId() const + { + return iId; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::GetMessageId +// ----------------------------------------------------------------------------- +void TBTGPSNmeaParser::GetMessageId() + { + iId = ENmeaUnknown; + Reset(); + TPtrC8 address; + if(GetFieldBlock(ENmeaFieldAddressField,address)==KErrNone) + { + for(TInt i=0; + i=messageId+KNmeaMessageIdSkip) + { + return KErrNotFound; + } + + //Skip address field and other fields + if(messageId != ENmeaNull) + { + for(TInt i=0; i +TInt TBTGPSNmeaParser::GetFieldData(TInt aFieldId, TReal32& aData) const + { + TPtrC8 fieldBlock; + TInt err = GetFieldBlock(aFieldId, fieldBlock); + if(err==KErrNone && fieldBlock.Length()>0) + { + TLex8 lex(fieldBlock); + return lex.Val(aData, KDecimalSeperator); + } + return err; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::GetFieldData +// ----------------------------------------------------------------------------- +template <> +TInt TBTGPSNmeaParser::GetFieldData(TInt aFieldId, TReal& aData) const + { + TPtrC8 fieldBlock; + TInt err = GetFieldBlock(aFieldId, fieldBlock); + if(err==KErrNone && fieldBlock.Length()>0) + { + TLex8 lex(fieldBlock); + return lex.Val(aData, KDecimalSeperator); + } + return err; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::GetFieldData +// ----------------------------------------------------------------------------- +template <> +TInt TBTGPSNmeaParser::GetFieldData(TInt aFieldId, TInt& aData) const + { + TPtrC8 fieldBlock; + TInt err = GetFieldBlock(aFieldId, fieldBlock); + if(err==KErrNone && fieldBlock.Length()>0) + { + TLex8 lex(fieldBlock); + return lex.Val(aData); + } + return err; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::GetFieldData +// ----------------------------------------------------------------------------- +#define GetFieldDataImplementation(s) \ +template <> TInt TBTGPSNmeaParser::GetFieldData(TInt aFieldId, s& aData) const \ + { \ + TPtrC8 fieldBlock; \ + TInt err = GetFieldBlock(aFieldId, fieldBlock); \ + if(err==KErrNone && fieldBlock.Length()>0) \ + { \ + TLex8 lex(fieldBlock); \ + return lex.Val(aData); \ + } \ + return err; \ + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::NextFieldData +// ----------------------------------------------------------------------------- +template +TInt TBTGPSNmeaParser::NextFieldData(T& aData) const + { + //This function must be called when the sentence is valid + __ASSERT_DEBUG(IsValid(), Panic(EPanicInvalidNmeaSentence)); + + TBuf8 fieldBuf; + TPtrC8 fieldBlock(fieldBuf); + TInt err = GetNext(fieldBlock); + if(err==KErrNone) + { + TLex8 lex(fieldBlock); + return lex.Val(aData); + } + return err; + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::CheckValidity +// ----------------------------------------------------------------------------- +TBool TBTGPSNmeaParser::CheckValidity() const + { + TInt length = iNmea.Length(); + + //Check the length of the NMEA sentence + if(length length)) + { + return EFalse; + } + + //Get checsum field + TLex8 lex(iNmea.Mid(checksumDelimiterPos, KNmeaChecksumFieldLength)); + + //Check checksum + return VerifyChecksum(iNmea); + } + +// ----------------------------------------------------------------------------- +// TBTGPSNmeaParser::TrimSentence +// ----------------------------------------------------------------------------- +const TPtrC8 TBTGPSNmeaParser::TrimSentence() const + { + //Check checksum + TInt checksumDelimiterPos = iNmea.LocateReverse(KNmeaChecksumDelimiter); + + return iNmea.Mid( + KNmeaDataStartPos, + checksumDelimiterPos-KNmeaDataStartPos); + } + + +// ---------------------------------------------------------------------------- +// TBTGPSNmeaParser::VerifyChecksum +// ---------------------------------------------------------------------------- +// +TBool TBTGPSNmeaParser::VerifyChecksum(const TDesC8& aSentence) const + { + TUint8 checksum = 0; + TInt i; + TInt length = aSentence.Length(); + for (i = KNmeaDataStartPos; + i < length && aSentence[i] != KNmeaChecksumDelimiter; i++) + { + checksum ^= aSentence[i]; + } + + if (++i + KNmeaDataStartPos < aSentence.Length()) + { + TUint8 sum = TUint8((CharToNibble(aSentence[i]) << 4) + + CharToNibble(aSentence[i+1])); + if (sum == checksum) + { + return ETrue; + } + } + + return EFalse; + } + +// ---------------------------------------------------------------------------- +// TBTGPSNmeaParser::CharToNibble +// ---------------------------------------------------------------------------- +// +TUint8 TBTGPSNmeaParser::CharToNibble(const TUint8 aChar) const + { + if (aChar <= '9') + { + return TUint8(aChar - '0'); + } + else + { + return TUint8(aChar - 'A' + 10); + } + } + +// End of File + + +