diff -r a2efdd544abf -r b47902b73a93 datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/BTGPSFix.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/BTGPSFix.cpp Fri Jun 04 10:34:15 2010 +0100 @@ -0,0 +1,1088 @@ +// 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 +#include +#include // TPositionSatelliteInfo +#include "BTGPSLogging.h" +#include "BTGPSRequestHandler.h" +#include "BTGPSConstantsManager.h" +#include "BTGPSFix.h" +#include "BTGPSLogging.h" +#include "BTGPSNmeaParser.h" +#include "BTGPSNmeaBuffer.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +//The knots to m/s conversion multiplier +const TReal64 KKnotInMetersPerSecond = 0.5144; + +//Hardcoded accuracy +const TReal32 KHorizontalAccuracy = 10.0; +const TReal32 KVerticalAccuracy = 30.0; + +//Decimal seperator +const TUint8 KDecimalSeperator = '.'; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CBTGPSFix::CBTGPSFix +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +CBTGPSFix::CBTGPSFix() + { + Reset(); + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::SetNmeaBuffer +// Set NMEA Buffer +// ----------------------------------------------------------------------------- +void CBTGPSFix::SetNmeaBuffer(CBTGPSNmeaBuffer* aNmeaBuffer) + { + iNmeaBuffer = aNmeaBuffer; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::Reset +// Reset the fix parameters. +// ----------------------------------------------------------------------------- +void CBTGPSFix::Reset() + { + TRACESTRING("CBTGPSFix::Reset") + ResetFix(); + + ResetGSVTime(); + + iNumberOfSatellites = 0; + iSatelliteArray.Reset(); + for(TInt i=0; iResetBuffer(); + } + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ResetFix +// ----------------------------------------------------------------------------- +void CBTGPSFix::ResetFix() + { + TRACESTRING("CBTGPSFix::ResetFix start...") + TRealX nan; + nan.SetNaN(); + + ResetPosition(); + + iSpeed=nan; + iHeading=nan; + + iUsedSatellitesArray.Reset(); + iSatelliteTime = TTime(0); + + iHorizontalDoP = nan; + iVerticalDoP = nan; + iPositionDoP = nan; + iSatellitesUsed = 0; + + //Clear the mask + iReceivedMsgMask = 0; + + iGpsMode = EGpsModeSatellite; + TRACESTRING("CBTGPSFix::ResetFix end") + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ResetGSVTime +// ----------------------------------------------------------------------------- +void CBTGPSFix::ResetGSVTime() + { + TRACESTRING("CBTGPSFix::ResetGSVTime start...") + iGsvTime = TTime(0); + TRACESTRING("CBTGPSFix::ResetGSVTime end"); + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ResetPosition +// +// ----------------------------------------------------------------------------- +void CBTGPSFix::ResetPosition() + { + TRACESTRING("CBTGPSFix::ResetPosition start...") + TRealX nan; + nan.SetNaN(); + + iLatitude = nan; + iLongitude = nan; + iAltitude = nan; + iTime = TTime(0); + + iValid = CBTGPSFix::EFixValidityUnkown; + TRACESTRING("CBTGPSFix::ResetPosition end") + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::FixState +// ----------------------------------------------------------------------------- +CBTGPSFix::TState CBTGPSFix::FixState() const + { + return iValid; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::IsFixValid +// +// ----------------------------------------------------------------------------- +TBool CBTGPSFix::IsFixValid() const + { + return (iValid == EFixValid2D || iValid == EFixValid3D); + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::IfFullNmeaPatternReceived +// +// ----------------------------------------------------------------------------- +TBool CBTGPSFix::IfFullNmeaPatternReceived() const + { + return iReceivedMsgMask == (EReceivedGSA|EReceivedGGA|EReceivedRMC); + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::FixTime +// +// ----------------------------------------------------------------------------- +TTime CBTGPSFix::FixTime() const + { + return iTime; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::GsvTime +// +// ----------------------------------------------------------------------------- +TTime CBTGPSFix::GsvTime() const + { + return iGsvTime; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ParseMessage +// Fills the information available from a command to the fix +// ----------------------------------------------------------------------------- +CBTGPSFix::TParsingStatus CBTGPSFix::ParseMessage(const TBTGPSNmeaParser& aParser) + { + TRACESTRING("CBTGPSFix::ParseMessage start...") + TRAPD(err, ParseMessageL(aParser)); + TParsingStatus ret = EUnkown; + switch(err) + { + case KErrNone: + ret = EInfoUpdated; + break; + case KErrNotSupported: + ret = EUnkown; + break; + default: + ret = EInvalid; + } + TRACESTRING("CBTGPSFix::ParseMessage end") + return ret; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ParseMessageL +// Fills the information available from a command to the fix +// ----------------------------------------------------------------------------- +void CBTGPSFix::ParseMessageL(const TBTGPSNmeaParser& aParser) + { + if(!aParser.IsValid()) + { + User::Leave(KErrCorrupt); + } + + switch (aParser.MessageId()) + { + case ENmeaGPGSV: + ParseGSVSentenceL(aParser); + break; + + case ENmeaGPRMC: + ParseRMCSentenceL(aParser); + break; + + case ENmeaGPGGA: + ParseGGASentenceL(aParser); + break; + + case ENmeaGPGSA: + ParseGSASentenceL(aParser); + break; + + default: + User::Leave(KErrNotSupported); + break; + } + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ParseGGASentenceL +// +// ----------------------------------------------------------------------------- +void CBTGPSFix::ParseGGASentenceL( + const TBTGPSNmeaParser& aParser) + { + + GetLatitudeLongitude(aParser, ENmeaFieldGPGGALatitude); + + //Get GPS Quality indicator. + //By default, assume GPS works in normal mode + TInt gpsQualityIndicator(EGpsQualitySPS); + if(aParser.GetFieldData(ENmeaFieldGPGGAFix, gpsQualityIndicator)==KErrNone) + { + //Get satellite mode + switch(gpsQualityIndicator) + { + case EGpsQualityManualInput: + iGpsMode = EGpsModeManualInput; + break; + case EGpsQualityNotValid: + iGpsMode = EGpsModeInvalid; + break; + case EGpsQualityEstimated: + iGpsMode = EGpsModeEstimated; + break; + case EGpsQualitySimulation: + iGpsMode = EGpsModeSimulator; + break; + case EGpsQualitySPS: + case EGpsQualityDGPS: + case EGpsQualityPPS: + case EGpsQualityRTK: + case EGpsQualityFloatRTK: + default: + //Specify any value other than those defined in NMEA spec as + //Satellite mode. This will enable PSY working with mal-functioning + //GPS and future GPS technology. + iGpsMode = EGpsModeSatellite; + break; + } + } + + //Get number of satellites in use + aParser.GetFieldData( + ENmeaFieldGPGGASatellitesUsed, + iSatellitesUsed); + + //Get HDOP + aParser.GetFieldData( + ENmeaFieldGPGGAHDOP, + iHorizontalDoP); + + //Acquire altitude over msl + TReal tempVal32(0); + aParser.GetFieldData( + ENmeaFieldGPGGAMSLAltitude, + tempVal32); + + //Get Geoidal seperation + aParser.GetFieldData( + ENmeaFieldGPGGAGeoidalSeperation, + iGeoidalSeperation); + + //Caculate altitude over WGS84 + iAltitude = tempVal32+iGeoidalSeperation; + + //GGA received + iReceivedMsgMask = iReceivedMsgMask | EReceivedGGA; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ParseGSVSentenceL +// +// ----------------------------------------------------------------------------- +void CBTGPSFix::ParseGSVSentenceL( + const TBTGPSNmeaParser& aParser) + { + //Get message number + TInt messageNumber(1); + User::LeaveIfError(aParser.GetFieldData( + ENmeaFieldGPGSVMessageNumber, + messageNumber)); + + //Check validity of message number + if(messageNumber>KMaxGSVMessageNumber) + { + User::Leave(KErrCorrupt); + } + + if(messageNumber == 1) + { + //Get total number messages + TInt totalNumberOfMessages(iGsvTotalNumberOfMessage); + User::LeaveIfError(aParser.GetFieldData( + ENmeaFieldGPGSVNumberOfMessage, + totalNumberOfMessages)); + iGsvTotalNumberOfMessage = totalNumberOfMessages; + + //Get satellites in view + TInt satellitesInView(iGsvSatelliteInView); + aParser.GetFieldData( + ENmeaFieldGPGSVSatellitesInView, + satellitesInView); + + iGsvSatelliteInView = satellitesInView; + + //Clear cache + for(TInt i=0; i time; + + //Get date and time field + TPtrC8 dateField; + aParser.GetFieldBlock( + ENmeaFieldGPRMCDate, + dateField); + + //Get time field + TPtrC8 timeField; + aParser.GetFieldBlock( + ENmeaFieldGPRMCUTCTime, + timeField); + + if(dateField.Length()==6 && + timeField.Length()>0 && + timeField.Length()<=10) + { + //Date consist of DDMMYY + TBuf16<6> date; + date.Copy(dateField); + + time.Append(_L("20")); + time.Append(date.Mid(4,2)); + + //Take care that the month is indexed from zero + TInt tempVal(1); + TLex tempLexer = date.Mid(2,2); + tempLexer.Val(tempVal); //error ignored + tempVal = tempVal - 1; + time.AppendNumFixedWidth(tempVal,EDecimal,2); + + //Take care that the date is indexed from zero + tempLexer = date.Mid(0,2); + tempVal = 1; + tempLexer.Val(tempVal); //error ignored + tempVal = tempVal - 1; + time.AppendNumFixedWidth(tempVal,EDecimal,2); + time.Append(_L(":")); + + //Time consist of HHMMSS.SSS + TBuf16<10> times; + + times.Copy(timeField); + time.Append(times); + + iSatelliteTime.Set(time);//error ignored + } + + //Get latitude and longitude + GetLatitudeLongitude(aParser, ENmeaFieldGPRMCLatitude); + + //Get speed + TReal32 tempVal32(0); + if(aParser.GetFieldData( + ENmeaFieldGPRMCSpeedOverGround, + tempVal32)==KErrNone) + { + iSpeed = KKnotInMetersPerSecond*tempVal32; + } + + //Get heading + aParser.GetFieldData( + ENmeaFieldGPRMCCourseOverGround, + iHeading); + + //Get GPS Mode + TPtrC8 gpsMode; + aParser.GetFieldBlock( + ENmeaFieldGPRMCModeIndicator, + gpsMode); + if(gpsMode.Length()!=0) + { + switch(gpsMode[0]) + { + case 'A': + case 'D': + iGpsMode = EGpsModeSatellite; + break; + case 'E': + iGpsMode = EGpsModeEstimated; + break; + case 'M': + iGpsMode = EGpsModeManualInput; + break; + case 'S': + iGpsMode = EGpsModeSimulator; + break; + case 'N': + default: + iGpsMode = EGpsModeInvalid; + break; + } + } + + //RMC received + iReceivedMsgMask = iReceivedMsgMask | EReceivedRMC; + + } + + +// ----------------------------------------------------------------------------- +// CBTGPSFix::GetLatitudeLongitude +// ----------------------------------------------------------------------------- +void CBTGPSFix::GetLatitudeLongitude( + const TBTGPSNmeaParser& aParser, + TInt aStartId) + { + TPtrC8 nsField; + TPtrC8 latField; + TPtrC8 ewField; + TPtrC8 logField; + + aParser.GetFieldBlock(aStartId, latField); + aParser.GetFieldBlock(aStartId+1, nsField); + aParser.GetFieldBlock(aStartId+2, logField); + aParser.GetFieldBlock(aStartId+3, ewField); + + //We retrieve position only when all fields are valid + if(nsField.Length()!=0 && latField.Length()!=0 && + ewField.Length()!=0 && logField.Length()!=0) + { + TReal latitude, longitude; + if( GetDegrees(nsField, latField, latitude) == KErrNone && + GetDegrees(ewField, logField, longitude) == KErrNone) + { + iLatitude = latitude; + iLongitude = longitude; + TRACESTRING2("lat=%f", latitude); + TRACESTRING2("lon=%f", longitude); + } + } + //Set fix time + iTime.UniversalTime(); + } + + +// ----------------------------------------------------------------------------- +// CBTGPSFix::GetDegrees +// Transforms from degrees and minutes string to degree float +// ----------------------------------------------------------------------------- +TInt CBTGPSFix::GetDegrees( + const TDesC8& aSide, + const TDesC8& aDegreesMinutes, + TReal64& aDegrees) + { + TInt err = KErrNone; + + _LIT8(compNS, "S"); + _LIT8(compEW, "W"); + _LIT8(decimalPoint, "."); + + aDegrees = 0.0; + TReal64 sign = 1.0; + + // Create sign multiplier according to N/S field + if ( 0 == aSide.Compare(compNS) || 0 == aSide.Compare(compEW) ) + { + sign = -1; + } + + TInt loop = aDegreesMinutes.Find(decimalPoint); + + //Check that the decimal point was in right place + //There could be 1-3 chars in degrees ([[D]D]DMM.MMMM) + if ( (KErrNotFound != loop) && (loop > 2) && (loop < 6) ) + { + loop -= 2; + + //Get the degrees (MM.MMM) + TLex8 numberLexer = aDegreesMinutes.Mid(loop); + err = numberLexer.Val(aDegrees, KDecimalSeperator); + + //Get the minutes (DDD) + numberLexer = aDegreesMinutes.Left(loop); + TReal64 temp = 0.0; + err |= numberLexer.Val( temp, KDecimalSeperator ); + + if(err!=KErrNone) + { + return err; + } + + //Degrees are calculate as sign*(DD+(MM.MMM/60)) + aDegrees = (temp) + aDegrees/60; + aDegrees = aDegrees * sign; + } + return err; + } + + +// ----------------------------------------------------------------------------- +// CBTGPSFix::AppendSatelliteData +// Fills the internal vector with satellite data +// ----------------------------------------------------------------------------- +void CBTGPSFix::AppendSatelliteData(TSatelliteInfo& aSatInfo) + { + //Prevent over indexing + if ( KMaxNumberOfSatellites > iNumberOfSatellites ) + { + iSatelliteArray[iNumberOfSatellites] = aSatInfo; + ++iNumberOfSatellites; + } + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ExtractSatelliteDataL +// ------------------------------------------------------------------------------ +void CBTGPSFix::ExtractSatelliteDataL ( + const TBTGPSNmeaParser& aParser, + TInt aField1, + TInt aField2, + TInt aField3, + TInt aField4) + { + TSatelliteInfo satInfo; + + satInfo.iSatelliteId = -1; + satInfo.iElevation = -1; + satInfo.iAzimuth = -1; + satInfo.iSNR = -1; + + TInt err = KErrNone; + err = aParser.GetFieldData(aField1, satInfo.iSatelliteId); + + err |= aParser.GetFieldData(aField2, satInfo.iElevation); + + err |= aParser.GetFieldData(aField3, satInfo.iAzimuth); + + err |= aParser.GetFieldData(aField4, satInfo.iSNR); + + if(err==KErrNone) + { + AppendSatelliteData(satInfo); + } + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::SecureCopy +// ------------------------------------------------------------------------------ +TBool CBTGPSFix::SecureCopy(TDes8& aTo,const TDesC8& aFrom) + { + //Prevent overflow + if ( aFrom.Length() > aTo.MaxLength() ) + { + //Cut the message + aTo.Copy(aFrom.Left(aTo.MaxLength())); + return EFalse; + } + else + { + aTo.Copy(aFrom); + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::FillPositionInfo +// ------------------------------------------------------------------------------ +TInt CBTGPSFix::FillPositionInfo( + TPositionInfoBase& aPosInfo, + TInt* aNmeaIndex) const + { + TRAPD(err, FillPositionInfoL(aPosInfo,aNmeaIndex)); + return err; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::FillPositionInfoL +// ------------------------------------------------------------------------------ +void CBTGPSFix::FillPositionInfoL( + TPositionInfoBase& aPosInfo, + TInt* aNmeaIndex ) const + { + TRACESTRING("CBTGPSFix::FillPositionInfo start...") + //HPositionGenericInfo + //--------------------------------------------------------------- + if ( aPosInfo.PositionClassType() & EPositionGenericInfoClass ) + { + HPositionGenericInfo* posInfo = + static_cast(&aPosInfo); + + if ( posInfo->IsRequestedField(EPositionFieldHorizontalSpeed) ) + { + if ( IsFixValid() ) + { + User::LeaveIfError(posInfo->SetValue(EPositionFieldHorizontalSpeed, + static_cast(iSpeed))); + } + } + + if ( posInfo->IsRequestedField(EPositionFieldHeading) ) + { + if ( IsFixValid() ) + { + User::LeaveIfError(posInfo->SetValue(EPositionFieldHeading, + static_cast(iHeading))); + } + } + + if ( posInfo->IsRequestedField(EPositionFieldNMEASentences) ) + { + TUint8 messageNum=0; + if(aNmeaIndex!=NULL) + { + TRACESTRING("CBTGPSFix::FillPositionInfo fill nmea sentences") + TRACESTRING2("begining = %d", *aNmeaIndex) + TRACESTRING2("bottom = %d", iNmeaBuffer->CurrentIndex()) + TInt beginning = *aNmeaIndex; + TBuf8 nmeaBuf; + while(iNmeaBuffer->ReadSentences( + nmeaBuf, + beginning) == KErrNone) + { + User::LeaveIfError(posInfo->SetValue(static_cast( + EPositionFieldNMEASentencesStart+messageNum), + nmeaBuf)); + ++messageNum; + } + + *aNmeaIndex = beginning; + } + + User::LeaveIfError(posInfo->SetValue(EPositionFieldNMEASentences, + static_cast(messageNum))); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumInView) ) + { + User::LeaveIfError(posInfo->SetValue(EPositionFieldSatelliteNumInView, + static_cast(iNumberOfSatellites))); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumUsed) ) + { + User::LeaveIfError(posInfo->SetValue(EPositionFieldSatelliteNumUsed, + static_cast(iSatellitesUsed))); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteTime) ) + { + User::LeaveIfError( + posInfo->SetValue( + EPositionFieldSatelliteTime, + iSatelliteTime)); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteHorizontalDoP) ) + { + User::LeaveIfError( + posInfo->SetValue( + EPositionFieldSatelliteHorizontalDoP, + static_cast(iHorizontalDoP))); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteVerticalDoP) ) + { + User::LeaveIfError( + posInfo->SetValue( + EPositionFieldSatelliteVerticalDoP, + static_cast(iVerticalDoP))); + } + + if ( posInfo->IsRequestedField(EPositionFieldSatellitePositionDoP) ) + { + User::LeaveIfError( + posInfo->SetValue( + EPositionFieldSatellitePositionDoP, + static_cast(iPositionDoP))); + } + } + + + //TpositionSatelliteInfo + //--------------------------------------------------------------- + if ( aPosInfo.PositionClassType() & EPositionSatelliteInfoClass ) + { + TPositionSatelliteInfo* posInfo = + static_cast(&aPosInfo); + posInfo->ClearSatellitesInView(); + TSatelliteData satData; + + //Iterate through the satellites + for ( TInt i = 0; i < iNumberOfSatellites;++i ) + { + satData.SetSatelliteId(iSatelliteArray[i].iSatelliteId); + satData.SetAzimuth(iSatelliteArray[i].iAzimuth); + satData.SetElevation(iSatelliteArray[i].iElevation); + satData.SetIsUsed(EFalse); + + //Find out if the this satellite was used in fix calculation + for ( TInt ii = 0; ii < iSatellitesUsed; ii++) + { + if ( iUsedSatellitesArray[ii] == + iSatelliteArray[i].iSatelliteId ) + { + //This satellite is used in solution + satData.SetIsUsed(ETrue); + ii = iSatellitesUsed; //Break the loop + } + } + + satData.SetSignalStrength(iSatelliteArray[i].iSNR); + posInfo->AppendSatelliteData(satData); + } + + posInfo->SetSatelliteTime(iSatelliteTime); + posInfo->SetVerticalDoP(iVerticalDoP); + posInfo->SetHorizontalDoP(iHorizontalDoP); + } + + + //TPositionCourseInfo + //--------------------------------------------------------------- + if ( aPosInfo.PositionClassType() & EPositionCourseInfoClass ) + { + TPositionCourseInfo* posInfo = + static_cast(&aPosInfo); + TCourse cos; + + if ( IsFixValid() ) + { + cos.SetSpeed(iSpeed); + cos.SetHeading(iHeading); + } + + posInfo->SetCourse(cos); + } + + + + //TPositionInfo + //--------------------------------------------------------------- + if ( aPosInfo.PositionClassType() & EPositionInfoClass ) + { + TPositionInfo * posInfo = static_cast(&aPosInfo); + TPosition pos; + + if ( IsFixValid() ) + { + if ( iValid == CBTGPSFix::EFixValid2D ) + { + pos.SetCoordinate(iLatitude,iLongitude); + } + else + { + pos.SetCoordinate(iLatitude,iLongitude,iAltitude); + } + + //Do a sanity check for the DOP values. If they are not valid, + //use hard coded values instead. + if ( (iHorizontalDoP > 0.0) && (iVerticalDoP > 0.0) ) + { + pos.SetAccuracy( + CBTGPSRequestHandler::ConstantsManager().iUserEquivalentRangeError + * iHorizontalDoP, + CBTGPSRequestHandler::ConstantsManager().iUserEquivalentRangeError + * iVerticalDoP); + } + else + { + pos.SetAccuracy(KHorizontalAccuracy,KVerticalAccuracy); + } + } + + pos.SetTime(iTime); + pos.SetDatum(KPositionDatumWgs84); + posInfo->SetPosition(pos); + } + TRACESTRING("CBTGPSFix::FillPositionInfo end"); + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::ValidateNmeaBufferIndex +// ------------------------------------------------------------------------------ +void CBTGPSFix::ValidateNmeaBufferIndex( + TInt& aNmeaIndex, + TInt& aBottom) const + { + TRACESTRING("CBTGPSFix::ValidateNmeaBufferIndex: start"); + TRACESTRING2("aNmeaIndex: %d", aNmeaIndex); + TRACESTRING2("aBottom : %d", aBottom); + TRACESTRING2("currentBot: %d", iNmeaBuffer->CurrentIndex()); + + TInt currentBottom = iNmeaBuffer->CurrentIndex(); + + //when aNmeaIndex==KBTGPSNmeaIndexNotSet, client shall + //get all NMEA data in the buffer + + //aBottom is the bottom of the NMEA buffer that the client + //last time seen. + //When aBottom==KBTGPSNmeaIndexNotSet, it means the client + //has just constructed. At this time, we don't need to check + //the index + + if(aNmeaIndex != KBTGPSNmeaIndexNotSet + && aBottom != KBTGPSNmeaIndexNotSet) + { + + //If index falles in the middle of aBottom and currentBottom, + //we shall invalidate the index + + if( ( aNmeaIndex>aBottom && aNmeaIndexcurrentBottom && aNmeaIndex > aBottom ) || + ( currentBottom > aNmeaIndex && aBottom > currentBottom ) ) + { + //Invalidate aNmeaIndex + aNmeaIndex = KBTGPSNmeaIndexNotSet; + + TRACESTRING("CBTGPSFix::ValidateNmeaBufferIndex: Index reset"); + } + } + + //Update aBottom + aBottom = currentBottom; + } + +// ----------------------------------------------------------------------------- +// CBTGPSFix::operator = +// ------------------------------------------------------------------------------ +void CBTGPSFix::operator =(const CBTGPSFix& aFix) + { + //This class is flat. We can just copy memory + Mem::Copy(this, &aFix, sizeof(CBTGPSFix)); + } + + +// End of File +