datasourcemodules/simulationpositioningmodule/src/EPos_CPosNmeaController.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datasourcemodules/simulationpositioningmodule/src/EPos_CPosNmeaController.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,307 @@
+// Copyright (c) 2005-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 "EPos_CPosNmeaController.h"
+#include "EPos_CPosFileHandler.h"
+#include "EPos_SimPsyConstants.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CPosNmeaController::CPosNmeaController(
+    TBool aTimeRelativePlayback) :
+    CPosControllerBase(aTimeRelativePlayback),
+    iHasAlreadyReadFirstSentence(EFalse), iState(EIdle)
+    {
+    CActiveScheduler::Add(this);   
+    iTimerTrigger.CreateLocal();
+    }
+
+// EPOC default constructor can leave.
+void CPosNmeaController::ConstructL(const TDesC& aNMEAFile)
+    {
+    iFileHandler = CPosFileHandler::NewL(aNMEAFile);
+    CPosSimulationPositioner::ClearAndSetDefaultPositionData(iPosition);
+    }
+
+// Two-phased constructor.
+CPosNmeaController* CPosNmeaController::NewL(
+    const TDesC& aNMEAFile,
+    TBool aTimeRelativePlayback)
+    {
+    CPosNmeaController* self = new (ELeave) CPosNmeaController(aTimeRelativePlayback);
+    CleanupStack::PushL(self);
+    self->ConstructL(aNMEAFile);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// Destructor
+CPosNmeaController::~CPosNmeaController()
+    {
+    iTimerTrigger.Cancel();
+    iTimerTrigger.Close();
+    Cancel();
+    delete iFileHandler;
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::NotifyPositionUpdate
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::NotifyPositionUpdate(
+    TPositionInfoBase& aPosInfo,
+    TRequestStatus& aStatus,
+    CPosSimulationPositioner& aSimPos)
+    {
+    NotifyPositionUpdateBase(aPosInfo, aStatus, aSimPos);
+
+    if(iState == EIdle && !IsActive())
+    	{
+    	iState = EWaiting;
+    	if(iTimeRelativePlayback)
+			{
+			iTimerTrigger.After(iStatus, iTimeBetweenReads);
+			}
+		else
+			{
+			TRequestStatus* status = &iStatus;
+			User::RequestComplete(status, KErrNone);
+			}
+		SetActive();
+    	}
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::CompleteRequest
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::CompleteRequest(TInt aErrorCode)
+    {
+    CompleteRequestBase(aErrorCode);
+	iParser.Reset();
+	if(aErrorCode == KErrNone && iTimeRelativePlayback)
+		{
+		StartTrpDelayTimer();
+		}
+	else
+		{
+		iState = EIdle;
+		}
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::ReadSentence
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::ReadSentence()
+    {
+    iState = EReadingSentence;
+    TRequestStatus* status = &iStatus;
+    
+    iStatus = iFileHandler->Read(iInputBuffer);
+    User::After(1);
+    User::RequestComplete(status, iStatus.Int());
+    SetActive();
+ 
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::ParseSentence
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::ParseSentence()
+    {
+    iState = EParsingSentence;
+    TInt err = iParser.ParseSentence(iInputBuffer, iPosition);
+    if(err != KPosErrorAlreadyParsed)
+    	{
+    	for(TInt i=0; i< iSimulationPositioners.Count(); i++)
+			{
+			//reading same information which were read into iParser
+			//so we can properly process all possible types of position:
+			//HPositionInfo, TPositionInfo, HPositionGenericInfo, TPositionCourseInfo,
+			//TPositionSatelliteInfo, etc.
+			iParser.ParseSentence(iInputBuffer, iSimulationPositioners[i].iPosition, ETrue);
+			}
+    	}
+    
+    if (err == KPosErrorAlreadyParsed)
+        {
+        // Make sure this sentence is kept until next request.
+        iHasAlreadyReadFirstSentence = ETrue;
+        CompleteOrRetry();
+        }
+    else if (err == KErrNone)
+        {
+        ReadSentence();
+        }
+    else
+        {
+        CompleteRequest(err);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::IsPartialPosition
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+TBool CPosNmeaController::IsPartialPosition(
+    TPositionInfoBase& aPosInfo)
+    {
+    TPositionInfo& posInfo = static_cast<TPositionInfo&> (aPosInfo);
+    TPosition pos;
+    posInfo.GetPosition(pos);
+
+    // Check if time is set
+    // Check if longitude is a number
+    // Check if latitude is a number
+    if (pos.Time().Int64() == 0 ||
+        Math::IsNaN(TRealX(pos.Longitude())) ||
+        Math::IsNaN(TRealX(pos.Latitude())))
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::CompleteOrRetry
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::CompleteOrRetry()
+    {
+    TInt progress = iParser.Progress();
+    TBool partialPosition = IsPartialPosition(iPosition);
+
+    if (progress == KPosAllParsed && !partialPosition)
+        {
+        // Full position fix
+        CompleteRequest(KErrNone);
+        return;
+        }
+    
+    if (partialPosition)
+        {
+        // Partial update position fix
+        CompleteRequest(KPositionPartialUpdate);
+        }
+    
+    //check for any outstanding requests
+    for(TInt i = 0; i < iSimulationPositioners.Count(); i++)
+    	{
+    		CPosSimulationPositioner::ClearAndSetDefaultPositionData(iSimulationPositioners[i].iPosition);
+    	}
+    if(iSimulationPositioners.Count()>0)
+        {
+        // Otherwise reset the parser and try again to get a full fix
+        iParser.Reset();
+        CPosSimulationPositioner::ClearAndSetDefaultPositionData(iPosition);
+
+        if (iHasAlreadyReadFirstSentence)
+            {
+            ParseSentence();
+            }
+        else
+            {
+            ReadSentence();
+            }
+        }
+    else if (iTimeRelativePlayback)
+    	{
+    	StartTrpDelayTimer();
+    	}
+    }
+
+void CPosNmeaController::StartTrpDelayTimer()
+	{
+	iState = EWaiting;
+	__ASSERT_ALWAYS(iTimeRelativePlayback, User::Panic(_L("CPosNmeaController"), KErrTotalLossOfPrecision ));
+	iTimerTrigger.After(iStatus, iTimeBetweenReads);
+	SetActive();
+	}
+// ----------------------------------------------------------------------------
+// CPosNmeaController::RunL
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::RunL()
+    {
+    switch (iState)
+    	{
+    	case EIdle:
+    	case EWaiting:
+    		if(iHasAlreadyReadFirstSentence)
+				{
+				iHasAlreadyReadFirstSentence = EFalse;
+				ParseSentence();
+				}
+			else
+				{
+				ReadSentence();
+				}
+    		break;
+    	case EReadingSentence:
+    		if (iStatus == KErrNone)
+    			{
+    			ParseSentence();
+    			}
+    		else if (iStatus == KErrEof)
+    			{
+    			CompleteOrRetry();
+    			}
+    		else
+    			{
+    			CompleteRequest(iStatus.Int());
+    			}
+    		break;
+    	case EParsingSentence:
+    	default:
+    		User::Panic(_L("CPosNmeaController state"), KErrGeneral);
+    	}
+
+    }
+
+// ----------------------------------------------------------------------------
+// CPosNmeaController::DoCancel
+//
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CPosNmeaController::DoCancel()
+    {
+    }
+
+//  End of File