diff -r 000000000000 -r 9cfd9a3ee49c datasourceadaptation/gpsdatasourceadaptation/common/src/utilfunctions.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datasourceadaptation/gpsdatasourceadaptation/common/src/utilfunctions.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,485 @@ +// Copyright (c) 2008-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: +// utility fucntions, and odds and sods for various bits of the location server +// +// + +/** + @file + @internalComponent + @deprecated +*/ + +#include +#include "utilfunctions.h" +#include "nmeafunctions.h" + +/** +Deep copy of position info data by type + +@param aTo the destination position info object reference +@param aFrom the source position info object reference +*/ +TInt CopyPositionTypes(TPositionInfoBase& aTo, const TPositionInfoBase& aFrom) + { + // check for self assignment + if(&aTo == &aFrom) + { + return KErrNone; + } + + return CopyPositionTypes2(aTo,aFrom); + } + +/** +Deep copy of position info data by type - +allows for source position to be smaller than destination position + +@param aTo the destination position info object reference +@param aFrom the source position info object reference +*/ +TInt CopyPositionTypes2(TPositionInfoBase& aTo, const TPositionInfoBase& aFrom) + { + const TUint32 toClassType = aTo.PositionClassType(); + const TUint toClassSize = aTo.PositionClassSize(); + const TUint32 fromClassType = aFrom.PositionClassType(); + const TUint fromClassSize = aFrom.PositionClassSize(); + + // check for self assignment + if(&aTo == &aFrom) + { + return KErrNone; // copy is implicit and already done :) + } + + // check we are not assigning base types + if(toClassSize == sizeof(TPositionInfoBase) + || fromClassSize == sizeof(TPositionInfoBase) + || toClassType == EPositionInfoUnknownClass // this the type of a TPositionInfoBase + || fromClassType == EPositionInfoUnknownClass) + { + return KErrArgument; // bad types - trying to copy between base types + } + // check the aTo type + TInt typeError = SupportedType(toClassType, toClassSize); + if(typeError != KErrNone) + { + return typeError; + } // i.e. KErrNotSupported + // check the aFromType + typeError = SupportedType(fromClassType, fromClassSize); + if(typeError != KErrNone) + { + return typeError; + } // i.e. KErrNotSupported + + if(toClassType & EPositionGenericInfoClass) + { + return CopyGenericPositionType(aTo, aFrom); + } + else + { + // Ok now we know we can copy these things from one to the other + // so here goes - the catch is we cannot overwrite the type and size + // of the destination, so we need a bit of pointer math. + // NB this relies on the being a class inheritance such that all of the + // types are derived from TPositionInfoBase first. Or the math goes + // haywire. This also implies a whole slew of assumptions about the ram + // layout of these classes.... + TUint8* baseToAddr = reinterpret_cast(&aTo)+sizeof(TPositionClassTypeBase); + const TUint8* const baseFromAddr = reinterpret_cast(&aFrom)+sizeof(TPositionClassTypeBase); + TUint32 dataLength = toClassSize-sizeof(TPositionClassTypeBase); // we copy only this many bytes form the source + TUint8* endAddr = Mem::Copy(baseToAddr, baseFromAddr, dataLength); + // Sanity check the Mem::Copy() - just in case... + if(endAddr != baseToAddr+dataLength) + { + return KErrGeneral; // Or KErrNoMemory? + } + else + { + return KErrNone; + } + } + } + +TInt CopyGenericPositionType(TPositionInfoBase& aTo, const TPositionInfoBase& aFrom) + { + TInt error; + HPositionGenericInfo* posInfo = static_cast(&aTo); + + // Have we got satellite info? + if(aFrom.PositionClassType() & EPositionSatelliteInfoClass) + { + const TPositionSatelliteInfo* satInfo = static_cast(&aFrom); + // copy any requested satellite info: + if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumInView) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteNumInView,static_cast(satInfo->NumSatellitesInView())); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumUsed) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteNumUsed, static_cast(satInfo->NumSatellitesUsed())); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteTime) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteTime, satInfo->SatelliteTime()); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteHorizontalDoP) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteHorizontalDoP, static_cast(satInfo->HorizontalDoP())); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteVerticalDoP) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteVerticalDoP, static_cast(satInfo->VerticalDoP())); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatelliteTimeDoP) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteTimeDoP, static_cast(satInfo->TimeDoP())); + if(error != KErrNone) + { + return error; + } + } + + if ( posInfo->IsRequestedField(EPositionFieldSatellitePositionDoP) ) + { + TReal64 pdop; + TReal64 hdop = satInfo->HorizontalDoP(); + TReal64 vdop = satInfo->VerticalDoP(); + if(!Math::IsNaN(hdop) && !Math::IsNaN(vdop)) + { + Math::Sqrt(pdop, hdop*hdop + vdop*vdop); + } + else + { + TRealX nan; + nan.SetNaN(); + pdop = nan; + } + error = posInfo->SetValue(EPositionFieldSatellitePositionDoP, static_cast(pdop)); + if(error != KErrNone) + { + return error; + } + } + } + // Have we got course info? + if(aFrom.PositionClassType() & EPositionCourseInfoClass) + { + // copy any requested course info: + const TPositionCourseInfo* courseInfo = static_cast(&aFrom); + TCourse course; + courseInfo->GetCourse(course); + + if ( posInfo->IsRequestedField(EPositionFieldHorizontalSpeed) ) + { + error = posInfo->SetValue(EPositionFieldHorizontalSpeed, static_cast(course.Speed())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldHorizontalSpeedError) ) + { + error = posInfo->SetValue(EPositionFieldHorizontalSpeedError, static_cast(course.SpeedAccuracy())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldVerticalSpeed) ) + { + error = posInfo->SetValue(EPositionFieldVerticalSpeed, static_cast(course.VerticalSpeed())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldVerticalSpeedError) ) + { + error = posInfo->SetValue(EPositionFieldVerticalSpeedError, static_cast(course.VerticalSpeedAccuracy())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldTrueCourse) ) + { + error = posInfo->SetValue(EPositionFieldTrueCourse, static_cast(course.Course())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldTrueCourseError) ) + { + error = posInfo->SetValue(EPositionFieldTrueCourseError, static_cast(course.CourseAccuracy())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldHeading) ) + { + error = posInfo->SetValue(EPositionFieldHeading, static_cast(course.Heading())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldHeadingError) ) + { + error = posInfo->SetValue(EPositionFieldHeadingError, static_cast(course.HeadingAccuracy())); + if(error != KErrNone) + { + return error; + } + } + } + // Have we got extended satellite info? + if(aFrom.PositionClassType() & EPositionExtendedSatelliteInfoClass) + { + // copy any requested course info: + const TPositionExtendedSatelliteInfo* extendedSatInfo = static_cast(&aFrom); + + if ( posInfo->IsRequestedField(EPositionFieldMagneticCourse) ) + { + error = posInfo->SetValue(EPositionFieldMagneticCourse, static_cast(extendedSatInfo->CourseOverGroundMagnetic())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldMagneticCourseError) ) + { + TCourse course; + extendedSatInfo->GetCourse(course); + error = posInfo->SetValue(EPositionFieldMagneticCourseError, static_cast(course.CourseAccuracy())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldMagneticHeading) ) + { + TCourse course; + extendedSatInfo->GetCourse(course); + error = posInfo->SetValue(EPositionFieldMagneticHeading, static_cast(course.Heading() - extendedSatInfo->MagneticVariation())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldMagneticHeadingError) ) + { + TCourse course; + extendedSatInfo->GetCourse(course); + error = posInfo->SetValue(EPositionFieldMagneticHeadingError, static_cast(course.HeadingAccuracy())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldSatelliteSeaLevelAltitude) ) + { + TPosition pos; + extendedSatInfo->GetPosition(pos); + error = posInfo->SetValue(EPositionFieldSatelliteSeaLevelAltitude, static_cast(pos.Altitude() + extendedSatInfo->GeoidalSeparation())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldSatelliteGeoidalSeparation) ) + { + error = posInfo->SetValue(EPositionFieldSatelliteGeoidalSeparation, static_cast(extendedSatInfo->GeoidalSeparation())); + if(error != KErrNone) + { + return error; + } + } + if ( posInfo->IsRequestedField(EPositionFieldNMEASentences) ) + { + TBuf8<128> buffer; + TUint8 sentences = 0; + CreateGga(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + CreateGll(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + CreateGsa(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + CreateGst(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + // we need at least a GSV, and after the first one we'll know exactly how many are needed + TInt totalGsvSentences = 1; + TInt lastGsvSentence = 0; + while(lastGsvSentence < totalGsvSentences) + { + CreateGsv(buffer, *extendedSatInfo, totalGsvSentences, lastGsvSentence); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + } + CreateRmc(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + CreateVtg(buffer, *extendedSatInfo); + error = posInfo->SetValue(EPositionFieldNMEASentencesStart+sentences, buffer); + if(error != KErrNone) + { + return error; + } + ++sentences; + error = posInfo->SetValue(EPositionFieldNMEASentences, sentences); + if(error != KErrNone) + { + return error; + } + + } + } + + //copy position info + __ASSERT_DEBUG( (aTo.PositionClassType() & EPositionInfoClass) && (aFrom.PositionClassType() & EPositionInfoClass), User::Invariant()); + + TPositionInfo* posInfoTo = static_cast(&aTo); + const TPositionInfo* posInfoFrom = static_cast(&aFrom); + TPosition posFrom; + posInfoFrom->GetPosition(posFrom); + + posInfoTo->SetPosition(posFrom); + posInfoTo->SetModuleId(posInfoFrom->ModuleId()); + posInfoTo->SetPositionMode(posInfoFrom->PositionMode()); + posInfoTo->SetPositionModeReason(posInfoFrom->PositionModeReason()); + posInfoTo->SetUpdateType(posInfoFrom->UpdateType()); + + return KErrNone; + } +/** +Check the size for supported position info type + +@param aType the position info type +@param aSize the size of specified type +@return Symbian standard error code +*/ +TInt SupportedType(const TUint32& aType, const TInt& aSize) + { + if(aType==EPositionInfoClass) + { + if(aSize!=sizeof(TPositionInfo)) + { + return KErrNotSupported; // something weird. Type ok but the size is wrong + } + } + else if(aType==(EPositionInfoClass|EPositionCourseInfoClass)) + { + if(aSize!=sizeof(TPositionCourseInfo)) + { + return KErrNotSupported; // something weird. Type ok but the size is wrong + } + } + else if(aType==(EPositionInfoClass|EPositionCourseInfoClass|EPositionSatelliteInfoClass)) + { + if(aSize!=sizeof(TPositionSatelliteInfo)) + { + return KErrNotSupported; // something weird. Type ok but the size is wrong + } + } + else if(aType==(EPositionInfoClass|EPositionCourseInfoClass|EPositionSatelliteInfoClass|EPositionExtendedSatelliteInfoClass)) + { + if(aSize!=sizeof(TPositionExtendedSatelliteInfo)) + { + return KErrNotSupported; // something weird. Type ok but the size is wrong + } + } + else if(aType == (EPositionInfoClass|EPositionGenericInfoClass)) + { + if(aSize < sizeof(HPositionGenericInfo)) + { + return KErrNotSupported; // something weird. Type ok but the size is wrong + } + } + else // no other types supported + { + return KErrNotSupported; + } + // othwerwise the size and type are what we expected + return KErrNone; + } + + +TBool Partial(const TPosition& aPos) + { + TBool partial = EFalse; + TReal64 lat = aPos.Latitude(); + TReal64 lng = aPos.Longitude(); + if(Math::IsNaN(lat) || Math::IsNaN(lng)) + { + partial = ETrue; + } + return partial; + } + +//