datasourceadaptation/gpsdatasourceadaptation/common/src/utilfunctions.cpp
author Pat Downey <patd@symbian.org>
Thu, 24 Jun 2010 11:27:31 +0100
changeset 42 8e58c1bec439
parent 0 9cfd9a3ee49c
permissions -rw-r--r--
Merge heads.

// 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;
	}

//