datasourceadaptation/gpsdatasourceadaptation/common/src/utilfunctions.cpp
changeset 0 9cfd9a3ee49c
--- /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 <lbssatellite.h>
+#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<TUint8*>(&aTo)+sizeof(TPositionClassTypeBase);			
+		const TUint8* const baseFromAddr = reinterpret_cast<const TUint8*>(&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<HPositionGenericInfo*>(&aTo);
+    
+    // Have we got satellite info?
+    if(aFrom.PositionClassType() & EPositionSatelliteInfoClass)	
+    	{
+    	const TPositionSatelliteInfo* satInfo = static_cast<const TPositionSatelliteInfo*>(&aFrom);
+    	// copy any requested satellite info:
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumInView) )
+            {
+            error = posInfo->SetValue(EPositionFieldSatelliteNumInView,static_cast<TInt8>(satInfo->NumSatellitesInView()));
+            if(error != KErrNone)
+            	{
+            	return error;
+            	}
+            }       
+
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteNumUsed) )
+            {
+            error = posInfo->SetValue(EPositionFieldSatelliteNumUsed, static_cast<TInt8>(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<TReal32>(satInfo->HorizontalDoP()));
+            if(error != KErrNone)
+            	{
+            	return error;
+            	}
+            }
+
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteVerticalDoP) )
+            {
+            error = posInfo->SetValue(EPositionFieldSatelliteVerticalDoP, static_cast<TReal32>(satInfo->VerticalDoP()));
+            if(error != KErrNone)
+            	{
+            	return error;
+            	}
+            }
+
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteTimeDoP) )
+            {
+            error = posInfo->SetValue(EPositionFieldSatelliteTimeDoP, static_cast<TReal32>(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<TReal32>(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<const TPositionCourseInfo*>(&aFrom);
+        TCourse course;
+        courseInfo->GetCourse(course);
+        
+        if ( posInfo->IsRequestedField(EPositionFieldHorizontalSpeed) )
+            {
+            error = posInfo->SetValue(EPositionFieldHorizontalSpeed, static_cast<TReal32>(course.Speed()));
+            if(error != KErrNone)
+            	{
+            	return error;
+            	}
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldHorizontalSpeedError) )
+            {
+            error = posInfo->SetValue(EPositionFieldHorizontalSpeedError, static_cast<TReal32>(course.SpeedAccuracy()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldVerticalSpeed) )
+            {
+            error = posInfo->SetValue(EPositionFieldVerticalSpeed, static_cast<TReal32>(course.VerticalSpeed()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldVerticalSpeedError) )
+            {
+            error = posInfo->SetValue(EPositionFieldVerticalSpeedError, static_cast<TReal32>(course.VerticalSpeedAccuracy()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldTrueCourse) )
+            {
+            error = posInfo->SetValue(EPositionFieldTrueCourse, static_cast<TReal32>(course.Course()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldTrueCourseError) )
+            {
+            error = posInfo->SetValue(EPositionFieldTrueCourseError, static_cast<TReal32>(course.CourseAccuracy()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldHeading) )
+            {
+            error = posInfo->SetValue(EPositionFieldHeading, static_cast<TReal32>(course.Heading()));
+            if(error != KErrNone)
+            	{
+            	return error;
+            	}
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldHeadingError) )
+            {
+            error = posInfo->SetValue(EPositionFieldHeadingError, static_cast<TReal32>(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<const TPositionExtendedSatelliteInfo*>(&aFrom);
+
+        if ( posInfo->IsRequestedField(EPositionFieldMagneticCourse) )
+            {
+            error = posInfo->SetValue(EPositionFieldMagneticCourse, static_cast<TReal32>(extendedSatInfo->CourseOverGroundMagnetic()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldMagneticCourseError) )
+            {
+            TCourse course;
+            extendedSatInfo->GetCourse(course);
+            error = posInfo->SetValue(EPositionFieldMagneticCourseError, static_cast<TReal32>(course.CourseAccuracy()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldMagneticHeading) )
+            {
+            TCourse course;
+            extendedSatInfo->GetCourse(course);
+            error = posInfo->SetValue(EPositionFieldMagneticHeading, static_cast<TReal32>(course.Heading() - extendedSatInfo->MagneticVariation()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldMagneticHeadingError) )
+            {
+            TCourse course;
+            extendedSatInfo->GetCourse(course);
+            error = posInfo->SetValue(EPositionFieldMagneticHeadingError, static_cast<TReal32>(course.HeadingAccuracy()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteSeaLevelAltitude) )
+            {
+            TPosition pos;
+            extendedSatInfo->GetPosition(pos);
+            error = posInfo->SetValue(EPositionFieldSatelliteSeaLevelAltitude, static_cast<TReal32>(pos.Altitude() + extendedSatInfo->GeoidalSeparation()));
+            if(error != KErrNone)
+                {
+                return error;
+                }
+            }
+        if ( posInfo->IsRequestedField(EPositionFieldSatelliteGeoidalSeparation) )
+            {
+            error = posInfo->SetValue(EPositionFieldSatelliteGeoidalSeparation, static_cast<TReal32>(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<TPositionInfo*>(&aTo);
+    const TPositionInfo* posInfoFrom = static_cast<const TPositionInfo*>(&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;
+	}
+
+//