datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/BTGPSPositioner.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:50:39 +0200
changeset 0 9cfd9a3ee49c
permissions -rw-r--r--
Revision: 201002 Kit: 201005

// 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 <e32base.h>
#include <lbs/epos_mpositionerstatus.h>
#include <ecom/implementationproxy.h>
#include <lbssatellite.h>

#include "BTGPSPositioner.h"
#include "BTGPSRequestHandler.h"
#include "BTGPSPanic.h"
#include "btgpspsy.hrh"
#include "BTGPSLogging.h"
#include "BTGPSNmeaBuffer.h"

// EXTERNAL DATA STRUCTURES

// EXTERNAL FUNCTION PROTOTYPES

// CONSTANTS
static const TImplementationProxy KFactoryPtr = 
IMPLEMENTATION_PROXY_ENTRY( KPosBTPSYImplUid, CBTGPSPositioner::NewL);

// MACROS

// LOCAL CONSTANTS AND MACROS

// MODULE DATA STRUCTURES

/**
*  The extension class for the CBTGPSPositioner
*  Stores the instance variables
*/
class TBTGPSExtension
    {
    public:
        /**
        * default constructor
        */
        TBTGPSExtension():
            iRequestHandler(NULL),
            iActive(EFalse),
            iPosInfo(NULL),
            iStatus(NULL)
            {
            }

        //Pointer to the request handler
        CBTGPSRequestHandler* iRequestHandler;

        //Is there request pending
        TBool iActive;

        //Pointer to the current position info
        TPositionInfoBase* iPosInfo;

        //Pointer to the current request status
        TRequestStatus* iStatus;
    };

// LOCAL FUNCTION PROTOTYPES

// FORWARD DECLARATIONS

// ============================= LOCAL FUNCTIONS ===============================

// ============================ MEMBER FUNCTIONS ===============================


// -----------------------------------------------------------------------------
// CBTGPSPositioner::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CBTGPSPositioner* CBTGPSPositioner::NewL(TAny* aConstructionParameters)
    {
    CBTGPSPositioner* self = new( ELeave ) CBTGPSPositioner;

    CleanupStack::PushL( self );
    self->ConstructL(aConstructionParameters);
    CleanupStack::Pop(self);

    return self;
    }


// -----------------------------------------------------------------------------
// CBTGPSPositioner::~CBTGPSPositioner
// Destructor.
// -----------------------------------------------------------------------------
//
CBTGPSPositioner::~CBTGPSPositioner()
    {
    TRACESTRING("CBTGPSPositioner::~CBTGPSPositioner")
    if ( iBTGPSExtension )
        {
        if ( iBTGPSExtension->iRequestHandler )
            {
            iBTGPSExtension->iRequestHandler->UnregisterPSY(this);
            }
		delete iBTGPSExtension;
        }
    }

// -----------------------------------------------------------------------------
// NotifyPositionUpdate implements Cpositioner::NotifyPositionUpdate
// Requests position info asynchronously.
// Returns: aPosInfo: A reference to a position info object. This object
//                    must be in scope until the request has completed.
//                    The position (TPosition) of this position info object
//                    must be in WGS84 geodetic datum.
//          aStatus: The request status
//
// -----------------------------------------------------------------------------
//
void CBTGPSPositioner::NotifyPositionUpdate(TPositionInfoBase& aPosInfo,
                                            TRequestStatus& aStatus)
    {
    TRACESTRING("CBTGPSPositioner::NotifyPositionUpdate")

    //Clear position info
    ClearPositionInfo(aPosInfo);
    
    const CBTGPSFix* fix = NULL;
    TTime maxAge;

    aStatus = KRequestPending;

    iBTGPSExtension->iPosInfo = &aPosInfo;
    iBTGPSExtension->iStatus = &aStatus;
    GetMaxAge(maxAge);

    //Check if last location can be used
    TInt result = iBTGPSExtension->iRequestHandler->LastLocation(fix,maxAge,
        IsPartialUpdateAllowed());

    if( result  == KErrNone )
        {
        TInt err(KErrNone);
        
        switch(fix->FixState())
            {
            case CBTGPSFix::EFixValidityUnkown:
                {
                //Should never happen
                TRACESTRING("CBTGPSPositioner::NotifyPositionUpdate: \
INTERNAL ERROR: CBTGPSFix::ENull.")
                err = KPositionQualityLoss;
                break;
                }
            case CBTGPSFix::EFixNotValid:
                {
                TRACESTRING("CBTGPSPositioner::NotifyPositionUpdate: \
Last known location: CBTGPSFix::ENotValid.")
                err = fix->FillPositionInfo(*(iBTGPSExtension->iPosInfo));
                if(err == KErrNone)
                    {
                    err = KPositionPartialUpdate;
                    }
                break;
                }
            case CBTGPSFix::EFixValid2D:
            case CBTGPSFix::EFixValid3D:
                {
                err = fix->FillPositionInfo(*(iBTGPSExtension->iPosInfo));
                break;
                }
            default:
                {
                //Should never happen
                TRACESTRING("CBTGPSPositioner::NotifyPositionUpdate: \
INTERNAL ERROR: fix unknown.")
                err = KErrGeneral;
                break;
                }
            }
            TRACESTRING2("CBTGPSPositioner::Complete request error = %d", err)
            User::RequestComplete(iBTGPSExtension->iStatus, err);
        }
    else
        {
        iBTGPSExtension->iActive = ETrue;
        iBTGPSExtension->iRequestHandler->AcquireLocation(this);
        }

    }


// -----------------------------------------------------------------------------
// CancelNotifyPositionUpdate implements Cpositioner::CancelNotifyPositionUpdate
// Cancels position info request.
// -----------------------------------------------------------------------------
//
void CBTGPSPositioner::CancelNotifyPositionUpdate()
    {
    TRACESTRING("CBTGPSPositioner::CancelNotifyPositionUpdate")

    if ( iBTGPSExtension->iActive )
        {
        iBTGPSExtension->iActive = EFalse;
        iBTGPSExtension->iPosInfo = NULL;
        iBTGPSExtension->iRequestHandler->CancelAcquireLocation(this);

        TRACESTRING2("CBTGPSPositioner::Complete request error = %d", KErrCancel)
        User::RequestComplete(iBTGPSExtension->iStatus,KErrCancel);
        }
    }


// -----------------------------------------------------------------------------
// TrackingOverridden implements Cpositioner::TrackingOverridden
// Indicate if the PSY has overridden tracking.
// -----------------------------------------------------------------------------
//
TBool CBTGPSPositioner::TrackingOverridden() const
    {
    return ETrue;
    }


// -----------------------------------------------------------------------------
// TrackingOverridden implements Cpositioner::TrackingOverridden
// Initiate a tracking session.
// -----------------------------------------------------------------------------
//
void CBTGPSPositioner::StartTrackingL(
                                const TTimeIntervalMicroSeconds& aInterval)
    {
    TRACESTRING("CBTGPSPositioner::StartTrackingL")
    iBTGPSExtension->iRequestHandler->TrackingSessionStartL(this,aInterval);
    }

// -----------------------------------------------------------------------------
// StopTracking implements Cpositioner::StopTracking
// Any outstanding requests will be cancelled.
// -----------------------------------------------------------------------------
//
void CBTGPSPositioner::StopTracking()
    {
    TRACESTRING("CBTGPSPositioner::StopTracking")
    iBTGPSExtension->iRequestHandler->TrackingSessionStop(this);
    }

// -----------------------------------------------------------------------------
// CBTGPSPositioner::RequestCompleteNotify implements
// MBTGPSRequestCompleteListener::RequestCompleteNotify
// -----------------------------------------------------------------------------
//
TBool CBTGPSPositioner::RequestCompleteNotify(
        const CBTGPSFix* aFix,
        TInt aErr)
    {
    TRACESTRING("CBTGPSPositioner::RequestCompleteNotify start...")
    TRACESTRING2("error = %d", aErr)
    TBool completed = EFalse;
    
    //Validate the NMEA Buffer index and bottom
    if(aFix!=NULL)
        {
        aFix->ValidateNmeaBufferIndex(
            iNmeaIndex,
            iNmeaBottom);
        }
    
    //If there was error, pass it
    if ( (aErr < 0) || (KPositionQualityLoss == aErr) || (aFix==NULL))
        {
        ClearPositionInfo(*iBTGPSExtension->iPosInfo);
        iBTGPSExtension->iActive = EFalse;

        TRACESTRING2("CBTGPSPositioner::Complete request error = %d", aErr)
        User::RequestComplete(iBTGPSExtension->iStatus,aErr);
        completed = ETrue;
        }
    //No error, complete with fix
    else
        {
        TRACESTRING2("fix type = %d", aFix->FixState());

        TInt err = KErrNone;
        
        switch(aFix->FixState())
            {
            case CBTGPSFix::EFixValidityUnkown:
            case CBTGPSFix::EFixNotValid:
                {
                if ( IsPartialUpdateAllowed() )
                    {
                    //Complete the fix when client accept partial update. 
                    //Otherwise, continue
                    completed = ETrue;
                    err = KPositionPartialUpdate;
                    }
                }
                break;
            case CBTGPSFix::EFixValid2D:
            case CBTGPSFix::EFixValid3D:
                completed = ETrue;
                err = KErrNone;
                break;
            default:
                {
                TRACESTRING("CBTGPSPositioner::RequestCompleteNotify: \
INTERNAL ERROR: fix unknown.")
                completed = ETrue;
                err = KErrGeneral;
                break;
                }
            }
        
        if(completed)
            {
            TInt nmeaIndex = iNmeaIndex;
            TInt fillErr = aFix->FillPositionInfo(
                *iBTGPSExtension->iPosInfo,
                &nmeaIndex);
            
            if(fillErr != KErrNone)
                {
                err = fillErr;
                }
            else
                {
                iNmeaIndex = nmeaIndex;
                }
                
            iBTGPSExtension->iActive = EFalse;

            TRACESTRING2("CBTGPSPositioner::Complete request error = %d", err)
            User::RequestComplete(iBTGPSExtension->iStatus,err);
            }
        
        }
    return completed;
    }

// -----------------------------------------------------------------------------
// CBTGPSPositioner::ReportStatus
// Reports the PSY status to the MLFW
// -----------------------------------------------------------------------------
void CBTGPSPositioner::ReportStatus(const TPositionModuleStatus& aStatus)
    {
    MPositionerStatus* statusInf = this->PositionerStatus();
    statusInf->ReportStatus(aStatus);
    }

// -----------------------------------------------------------------------------
// CBTGPSPositioner::SetInitialNmeaBufferBottom
// -----------------------------------------------------------------------------
void CBTGPSPositioner::SetInitialNmeaBufferBottom(TInt aIndex)
    {
    iNmeaIndex = aIndex;
    }

// -----------------------------------------------------------------------------
// CBTGPSPositioner::ClearPositionInfo
// Clears the position info
// -----------------------------------------------------------------------------
void CBTGPSPositioner::ClearPositionInfo(TPositionInfoBase& aPosInfo)
    {
    if (aPosInfo.PositionClassType() & EPositionSatelliteInfoClass)
        {
        // TPositionSatelliteInfo
        (void) new (&aPosInfo) (TPositionSatelliteInfo);
        }
    else if (aPosInfo.PositionClassType() & EPositionCourseInfoClass)
        {
        // TPositionCourseInfo
        (void) new (&aPosInfo) (TPositionCourseInfo);
        }
    else if (aPosInfo.PositionClassType() & EPositionGenericInfoClass)
        {
        // HPositionGenericInfo
        HPositionGenericInfo* genInfo =
            static_cast<HPositionGenericInfo*> ( &aPosInfo );
        
        genInfo->ClearPositionData();
        }
    else if (aPosInfo.PositionClassType() & EPositionInfoClass)
        {
        // TPositionInfo
        (void) new (&aPosInfo) (TPositionInfo);
        }
    else
        {
        // Unknown type, this should never happen
        // --> Panic if we get here
        Panic(EPanicUnknownPositioningClass);
        }

    aPosInfo.SetModuleId(ImplementationUid());
    }

// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
//
CBTGPSPositioner::CBTGPSPositioner()
    {
    iNmeaIndex = KBTGPSNmeaIndexNotSet;
    iNmeaBottom = KBTGPSNmeaIndexNotSet;
    }

// -----------------------------------------------------------------------------
// CBTGPSPositioner::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CBTGPSPositioner::ConstructL(TAny* aConstructionParameters)
    {
    // Must call BaseConstructL first thing during
    // construction.
    CLEARTRACELOG;
    
    TRACESTRING("CBTGPSPositioner::ConstructL")
    BaseConstructL(aConstructionParameters);

    iBTGPSExtension = new (ELeave) TBTGPSExtension;

    iBTGPSExtension->iRequestHandler = CBTGPSRequestHandler::GetInstanceL();
    iBTGPSExtension->iRequestHandler->RegisterPSYL(this);
    }


// ========================== OTHER EXPORTED FUNCTIONS =========================

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(
    TInt& aTableCount)
    {
    aTableCount =1;
    return &KFactoryPtr;
    }

//  End of File