--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datasourcemodules/defaultpositioningmodule/src/EPos_CPosRequestController.cpp Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,836 @@
+// Copyright (c) 2007-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 <ecom/ecom.h>
+
+#include <lbscommon.h>
+#include <lbspositioninfo.h>
+#include <lbs/epos_cposmodules.h>
+#include <lbs/epos_cposmoduleidlist.h>
+#include <lbs/epos_cpositioner.h>
+#include <lbssatellite.h>
+#include "epos_mposmodulestatusmanager.h"
+
+#include "EPos_CPosRequestController.h"
+#include "epos_cposrequestor.h"
+#include "epos_defaultproxycommon.h"
+#include "epos_cpospsylisthandler.h"
+#include "epos_cpospsyfixstatemanager.h"
+#include "epos_cposconstmanager.h"
+#include "epos_cposexternalgpsmonitor.h"
+#include "epos_posgenericinfouser.h"
+
+
+// ================= LOCAL FUNCTIONS =======================
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CPosRequestController::CPosRequestController(
+ CPosDefaultPositioner& aDefaultPositioner,
+ MPosModuleStatusManager& aModuleStatusManager)
+ :
+ iDefaultPositioner( aDefaultPositioner ),
+ iModuleStatusManager( aModuleStatusManager ),
+ iCurrentPsy( KErrNotFound )
+ {
+ }
+
+// EPOC default constructor can leave.
+void CPosRequestController::ConstructL(
+ MPosModuleSettingsManager& aSettingsManager )
+ {
+ TRACESTRING( "CPosRequestController::ConstructL start... " )
+
+ iPsyListHandler = CPosPsyListHandler::GetInstanceL();
+ iPsyListHandler->SetModuleSettingsManagerL(
+ aSettingsManager );
+ iPsyListHandler->AddListenerL( this );
+
+
+ iPsyFixStateManager = CPosPsyFixStateManager::GetInstanceL();
+ iPsyFixStateManager->AddListenerL( this );
+ iConstManager = CPosConstManager::GetInstanceL();
+
+ iExtGpsPsyMonitor = CPosExternalGpsMonitor::GetInstanceL(
+ iDefaultPositioner,
+ iModuleStatusManager );
+
+ //Construct cleanup timer
+ iCleanupTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+ TRACESTRING( "CPosRequestController::ConstructL end " )
+
+ }
+
+// Two-phased constructor.
+CPosRequestController* CPosRequestController::NewL(
+ CPosDefaultPositioner& aDefaultPositioner,
+ MPosModuleSettingsManager& aSettingsManager,
+ MPosModuleStatusManager& aModuleStatusManager )
+ {
+ CPosRequestController* self = new (ELeave)
+ CPosRequestController(
+ aDefaultPositioner,
+ aModuleStatusManager );
+
+ CleanupStack::PushL(self);
+ self->ConstructL(
+ aSettingsManager );
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// Destructor
+CPosRequestController::~CPosRequestController()
+ {
+ TRACESTRING( "CPosRequestController::destructor start... " )
+
+ if ( iPsyFixStateManager )
+ {
+ iPsyFixStateManager->RemoveListener( this );
+ iPsyFixStateManager->ReleaseInstance();
+ }
+
+ if ( iPsyListHandler )
+ {
+ iPsyListHandler->RemoveListener( this );
+ iPsyListHandler->ReleaseInstance();
+ }
+
+ if ( iConstManager )
+ {
+ iConstManager->ReleaseInstance();
+ }
+
+ if ( iExtGpsPsyMonitor )
+ {
+ iExtGpsPsyMonitor->ReleaseInstance(
+ iDefaultPositioner );
+ }
+
+ // Close all requestors
+ iRequestorArray.ResetAndDestroy();
+ iRequestorArray.Close();
+
+ //Close PSY List
+ iPsyList.Close();
+
+ // Cleanup timer
+ delete iCleanupTimer;
+
+ TRACESTRING( "CPosRequestController::destructor end... " )
+
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::NotifyPositionUpdate
+// ---------------------------------------------------------
+//
+void CPosRequestController::NotifyPositionUpdate(
+ TPositionInfoBase& aPosInfo,
+ TRequestStatus& aStatus)
+ {
+ TRACESTRING( "CPosRequestController::NotifyPositionUpdate start... " )
+
+ //Default Proxy can't handle simultaneous location request.
+ __ASSERT_DEBUG(
+ iPosRequestStatus == NULL,
+ DefaultProxyPanic( EDefaultProxyPanic_SimualtaneousLR ) );
+
+ aStatus = KRequestPending;
+ iPosRequestStatus = &aStatus;
+ iPosInfo = &aPosInfo;
+
+ //When location request received, clear cleanup timer
+ iCleanupTimer->Cancel();
+
+ TRAPD( err, StartPositionUpdateL() );
+ if( err != KErrNone )
+ {
+ CompleteRequest(err);
+ }
+
+ TRACESTRING( "CPosRequestController::NotifyPositionUpdate end " )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CancelNotifyPositionUpdate
+// ---------------------------------------------------------
+//
+void CPosRequestController::CancelNotifyPositionUpdate(TInt aCancelReason)
+ {
+ TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) start... " )
+
+ //Cancel location request with error to all loaded requestor
+ TInt loadedRequestorCount = iRequestorArray.Count();
+ for ( TInt i = 0; i < loadedRequestorCount; i++ )
+ {
+ CancelRequest( i, aCancelReason );
+ }
+
+ CompleteRequest(KErrCancel);
+
+ TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) end " )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CancelNotifyPositionUpdate
+// ---------------------------------------------------------
+//
+void CPosRequestController::CancelNotifyPositionUpdate()
+ {
+ TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate start... " )
+
+ // This is a real user cancel
+ CancelNotifyPositionUpdate(KErrCancel);
+
+ TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate end " )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CancelRequest
+// ---------------------------------------------------------
+//
+void CPosRequestController::CancelRequest( TInt aIndex, TInt aCancelReason )
+ {
+ TInt count = iRequestorArray.Count();
+ if ( aIndex < count )
+ {
+ CPosRequestor* requestor = iRequestorArray[aIndex];
+ if ( requestor->IsActive() )
+ {
+ //Notify external GPS PSY monitor that this PSY is not used.
+ iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() );
+ requestor->CancelWithReason(aCancelReason);
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CancelRequest
+// ---------------------------------------------------------
+//
+void CPosRequestController::CancelRequest( TPositionModuleId aPsyId )
+ {
+ TInt count = iRequestorArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CPosRequestor* requestor = iRequestorArray[i];
+ if ( requestor->ModuleId() == aPsyId &&
+ requestor->IsActive() )
+ {
+ //Notify external GPS PSY monitor that this PSY is not used.
+ iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() );
+ requestor->Cancel();
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::StartTrackingL
+// ---------------------------------------------------------
+//
+void CPosRequestController::StartTracking(
+ const TTimeIntervalMicroSeconds& /*aInterval*/)
+ {
+ //This function does nothing. Tracking will be started
+ //to any specific PSY only if this PSY will be used by
+ //Default Proxy.
+
+ TRACESTRING( "CPosRequestController::StartTracking" )
+
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::StopTracking
+// ---------------------------------------------------------
+//
+void CPosRequestController::StopTracking()
+ {
+ TRACESTRING( "CPosRequestController::StopTracking start..." )
+
+ //Stop tracking to all loaded PSYs
+ TInt loadedRequestorCount = iRequestorArray.Count();
+ for ( TInt i = 0; i < loadedRequestorCount; i++ )
+ {
+ iRequestorArray[i]->StopTracking();
+ }
+
+ TRACESTRING( "CPosRequestController::StopTracking end" )
+
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::StartPositionUpdateL
+// ---------------------------------------------------------
+//
+void CPosRequestController::StartPositionUpdateL()
+ {
+ TRACESTRING( "CPosRequestController::StartPositionUpdateL start..." )
+
+ //Rebuid PSY list if neccessary
+ if ( !iPsyListValid )
+ {
+ iPsyListHandler->GetPsyListL( iPsyList );
+ iPsyListValid = ETrue;
+ }
+
+ iFirstResult = KErrNotFound; // as if no enabled psys found
+ iCurrentPsy = KErrNotFound; // start from first module
+ TryNextPositioner();
+
+ if ( !IsLocationRequestOnGoing() )
+ {
+ CompleteRequest( iFirstResult );
+ }
+
+ TRACESTRING( "CPosRequestController::StartPositionUpdateL end" )
+
+ }
+
+
+// ---------------------------------------------------------
+// CPosRequestController::TryNextPositioner
+// ---------------------------------------------------------
+//
+void CPosRequestController::TryNextPositioner()
+{
+ TRACESTRING( "CPosRequestController::TryNextPositioner start..." )
+
+ // Find next enabled plugin we should try with
+ TInt count = iPsyList.Count();
+ while ( ++iCurrentPsy < count )
+ {
+ TPositionModuleId currentPsyId = iPsyList[iCurrentPsy];
+
+ TRACESTRING2( "PSY: %x", currentPsyId )
+
+ TUint32 classType = iPosInfo->PositionClassType();
+ if ( !iPsyListHandler->IsClassSupported(
+ classType,
+ currentPsyId ) )
+ {
+ //if the requested class is not supported, then we try next PSY
+ //in the PSY list
+
+ if ( iCurrentPsy == 0 )
+ {
+ //Error code fromt the first PSY
+ iFirstResult = KErrArgument;
+ }
+
+ continue;
+ }
+
+ TRAPD( err, TryPositionerL( currentPsyId ) );
+
+ TRACESTRING2( "Try PSY completion code = %d", err )
+
+ if( err == KErrNone )
+ {
+ //Location request is made to currentPsy. Check the fix state of
+ //current PSY, if current PSY can't give a fix, we load next PSY
+ if ( iPsyFixStateManager->GetPsyFixState( currentPsyId )
+ != CPosPsyFixStateManager::EPsyFixStateNo )
+ {
+ //break from here. Othsewise, try next PSY
+ break;
+ }
+ }
+ else
+ {
+ //In error case, we store the error code if needed and try next PSY
+ if ( iCurrentPsy == 0 )
+ {
+ //Error code fromt the first PSY
+ iFirstResult = err;
+ }
+ }
+ }
+
+ TRACESTRING( "CPosRequestController::TryNextPositioner end" )
+
+}
+
+// ---------------------------------------------------------
+// CPosRequestController::TryPositionerL
+// ---------------------------------------------------------
+//
+void CPosRequestController::TryPositionerL( TPositionModuleId aPsyId )
+ {
+ CPosRequestor* currentRequestor = NULL;
+
+
+ //Check device status of the PSY. If it's in error status,
+ //it will not be used at all.
+ TPositionModuleStatus moduleStatus;
+ iModuleStatusManager.GetModuleStatus(
+ aPsyId,
+ moduleStatus );
+ if ( moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceError )
+ {
+ TRACESTRING2( "PSY %x device error", aPsyId )
+
+ User::Leave( KErrGeneral );
+ }
+
+ //Find if the PSY is already loaded
+ TInt requestorCount = iRequestorArray.Count();
+ for ( TInt i = 0; i < requestorCount; i++ )
+ {
+ if ( iRequestorArray[i]->ModuleId() == aPsyId )
+ {
+ currentRequestor = iRequestorArray[i];
+ break;
+ }
+ }
+
+ if ( currentRequestor == NULL )
+ {
+ //PSY has not been loaded before, load it now
+ TRACESTRING2( "Loading Positioner: %x", aPsyId )
+ currentRequestor =
+ CPosRequestor::NewL(
+ iDefaultPositioner,
+ aPsyId,
+ *this,
+ *iPsyFixStateManager,
+ iModuleStatusManager );
+
+ CleanupStack::PushL( currentRequestor );
+
+ //Notify fix state manager that a PSY is loaded
+ iPsyFixStateManager->PsyLoadedL( aPsyId );
+
+ //Add this requestor to requestor array
+ User::LeaveIfError( iRequestorArray.Append(
+ currentRequestor ) );
+ CleanupStack::Pop( currentRequestor );
+ }
+
+ //Start tracking if needed
+ TTimeIntervalMicroSeconds interval = iDefaultPositioner.TrackingInterval();
+ if (interval.Int64() != 0 )
+ {
+ currentRequestor->StartTrackingL( interval );
+ }
+
+ //Make location request to current positioner
+ currentRequestor->MakeLocationRequestL( *iPosInfo );
+
+ //Notify external GPS PSY monitor that a PSY is used
+ iExtGpsPsyMonitor->PsyUsed( aPsyId );
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::LocationRequestCompleted
+// ---------------------------------------------------------
+//
+void CPosRequestController::LocationRequestCompleted(
+ TPositionModuleId aModuleId,
+ TInt aErr,
+ const TPositionInfoBase& aPosInfo,
+ TBool aIsPosInfoUpToDate )
+ {
+ TRACESTRING( "CPosRequestController::LocationRequestCompleted start..." )
+ TRACESTRING2( "PSY: %x", aModuleId )
+ TRACESTRING2( "Err: %d", aErr )
+ TRACESTRING2( "Is PosInfo Updated: %d", aIsPosInfoUpToDate )
+
+ //Notify the external GPS PSY monitor that a PSY in not used
+ iExtGpsPsyMonitor->PsyNotUsed( aModuleId );
+
+ TInt err = aErr;
+ if ( aErr == KPositionPartialUpdate && IsLocationRequestOnGoingOnNetworkPsy() )
+ {
+ //Partial update is returned when Network PSY is used.
+ //partial update is not forwarded to system. Instead, location
+ //request is made to the loaded PSY again.
+ TInt ignore;
+ TRAP( ignore, TryPositionerL( aModuleId ) );
+ }
+ else if ( aErr == KErrNone ||
+ aErr == KErrPositionBufferOverflow ||
+ aErr == KPositionPartialUpdate )
+ {
+ //Location request succeed or
+ //buffer over flow is returned from a PSY or
+ //partial update is returned when only GPS PSY is used
+
+ //Copy request info, and complete LR
+ if ( aIsPosInfoUpToDate )
+ {
+ __ASSERT_DEBUG(
+ aPosInfo.PositionClassSize() == iPosInfo->PositionClassSize(),
+ DefaultProxyPanic( EDefaultProxyPanic_PosInfoSizeMismatch ) );
+
+ Mem::Copy( iPosInfo, &aPosInfo, iPosInfo->PositionClassSize() );
+ }
+ else
+ {
+ TInt cpErr = CopyPosInfoClass( aPosInfo , *iPosInfo );
+ if ( cpErr != KErrNone && err == KErrNone )
+ {
+ err = cpErr;
+ }
+ }
+
+ if ( iPosInfo->ModuleId() != aModuleId )
+ {
+ err = KErrGeneral;
+ }
+
+ CompleteRequest( err );
+ }
+ else
+ {
+ if ( aModuleId == iPsyList[0] )
+ {
+ //Store the result from first PSY
+ iFirstResult = aErr;
+
+ //Store module ID of first positioner
+ iPosInfo->SetModuleId( aModuleId );
+ }
+ }
+
+ //This will cause the state change notification and generate fallback
+ //if it's a error case.
+ iPsyFixStateManager->SetPsyFixState( aModuleId, aErr );
+
+ if ( !IsLocationRequestOnGoing() )
+ {
+ CompleteRequest( iFirstResult );
+ }
+
+ TRACESTRING( "CPosRequestController::LocationRequestCompleted end" )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::IsLocationRequestOnGoing
+// ---------------------------------------------------------
+//
+TBool CPosRequestController::IsLocationRequestOnGoing() const
+ {
+ TInt count = iRequestorArray.Count();
+ for ( TInt i=0; i < count; i++ )
+ {
+ const CPosRequestor& requestor = *(iRequestorArray[i]);
+ if ( requestor.IsActive() )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy
+// ---------------------------------------------------------
+//
+TBool CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy() const
+ {
+ TInt count = iRequestorArray.Count();
+ for ( TInt i=0; i < count; i++ )
+ {
+ const CPosRequestor& requestor = *(iRequestorArray[i]);
+ if ( requestor.IsActive() &&
+ iPsyListHandler->IsModuleNetworkBased(
+ requestor.ModuleId() ) )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::PsyFixStateChanged
+// ---------------------------------------------------------
+//
+void CPosRequestController::PsyFixStateChanged(
+ TPositionModuleId aModuleId,
+ CPosPsyFixStateManager::TPsyFixState aFixState )
+ {
+ TRACESTRING( "CPosRequestController::PsyFixStateChanged start..." )
+ TRACESTRING2( "PSY: %x", aModuleId )
+ TRACESTRING2( "Fix state: %d", aFixState )
+
+ //If there is location request on going and
+ //current can't give a fix, we try next PSY
+ if( iPosRequestStatus && iCurrentPsy<iPsyList.Count() )
+ {
+ if ( aFixState == CPosPsyFixStateManager::EPsyFixStateNo &&
+ iPsyList[iCurrentPsy] == aModuleId )
+ {
+ TryNextPositioner();
+ }
+ }
+
+ TRACESTRING( "CPosRequestController::PsyFixStateChanged end" )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CompleteRequest
+// ---------------------------------------------------------
+//
+void CPosRequestController::CompleteRequest(TInt aCompleteCode)
+ {
+ TRACESTRING( "CPosRequestController::CompleteRequest start..." )
+ TRACESTRING2( "Completion code: %d", aCompleteCode )
+ TRACESTRING2( "Module Id: %x", iPosInfo->ModuleId() )
+
+ if (iPosRequestStatus)
+ {
+ User::RequestComplete(iPosRequestStatus, aCompleteCode);
+ iPosRequestStatus = NULL;
+
+ //Clear all location request if this is not
+ //a partial update
+ if ( aCompleteCode != KPositionPartialUpdate )
+ {
+ ClearLocationRequests();
+ }
+
+ //If there is still location request ongoing to other PSYs,
+ //start cleanup timer
+ TInt count = iRequestorArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iRequestorArray[i]->IsActive() )
+ {
+
+ if ( !iCleanupTimer->IsActive() )
+ {
+ iCleanupTimer->Start(
+ iConstManager->GetCleanupTimeoutValue().Int64(),
+ iConstManager->GetCleanupTimeoutValue().Int64(),
+ TCallBack( CleanupTimeoutCallback, this )
+ );
+ }
+ }
+ }
+ }
+ TRACESTRING( "CPosRequestController::CompleteRequest end" )
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::ClearLocationRequests
+// ---------------------------------------------------------
+//
+void CPosRequestController::ClearLocationRequests()
+ {
+ TInt count = iRequestorArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CancelRequest( i, KErrCancel);
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::PsyListChanged
+// ---------------------------------------------------------
+//
+void CPosRequestController::PsyListChanged(
+ const TPosPsyListChangeEvent& aEvent )
+ {
+ TRACESTRING( "CPosRequestController::PsyListChanged start..." )
+ TRACESTRING2( "Event type: %d", aEvent.iType )
+ TRACESTRING2( "PSY: %x", aEvent.iPsyId )
+
+ switch ( aEvent.iType )
+ {
+ case EPosPsyListChangeEventPsyDeleted:
+ {
+ //Cancel location request to this PSY
+ CancelRequest( aEvent.iPsyId );
+
+ if ( iCurrentPsy >= 0 && iCurrentPsy < iPsyList.Count() )
+ {
+ //If there is location request on going
+ if ( aEvent.iPsyId == iPsyList[iCurrentPsy] )
+ {
+ //fallback to next PSY
+ TryNextPositioner();
+ }
+ }
+ //Delete this PSY from the list
+ TInt index = iPsyList.Find( aEvent.iPsyId );
+ if ( index != KErrNotFound )
+ {
+ iPsyList.Remove( index );
+ }
+
+ //Unload this PSY
+ UnloadRequestor( aEvent.iPsyId );
+ }
+ break;
+ case EPosPsyListChangeEventListRebuild:
+ default:
+ //Rebuild the list
+ iPsyListValid = EFalse;
+ break;
+ }
+
+ TRACESTRING( "CPosRequestController::PsyListChanged end" )
+ }
+
+
+// ---------------------------------------------------------
+// CPosRequestController::GetRequestor
+// ---------------------------------------------------------
+//
+CPosRequestor* CPosRequestController::GetRequestor(
+ TPositionModuleId aPsyId )
+ {
+ TInt count = iRequestorArray.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iRequestorArray[i]->ModuleId() == aPsyId )
+ {
+ return iRequestorArray[i];
+ }
+ }
+ return NULL;
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::UnloadRequestor
+// ---------------------------------------------------------
+//
+void CPosRequestController::UnloadRequestor( TPositionModuleId aPsyId )
+ {
+ TRACESTRING( "CPosRequestController::UnloadRequestor" )
+ TRACESTRING2( "PSY: %x", aPsyId )
+
+ TInt count = iRequestorArray.Count();
+ for ( TInt i = count-1; i >= 0; i-- )
+ {
+ if ( iRequestorArray[i]->ModuleId() == aPsyId )
+ {
+ delete iRequestorArray[i];
+ iRequestorArray.Remove( i );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CopyPosInfoClass
+// ---------------------------------------------------------
+//
+TInt CPosRequestController::CopyPosInfoClass(
+ const TPositionInfoBase& aSrc,
+ TPositionInfoBase& aDst )
+ {
+ TInt err = KErrNone;
+
+ TUint32 srcClasses = aSrc.PositionClassType();
+ TUint32 dstClasses = aDst.PositionClassType();
+
+ //Handle TPositionInfoBase
+ aDst.SetModuleId( aSrc.ModuleId() );
+ aDst.SetUpdateType( aSrc.UpdateType() );
+
+ //Handle TPositionInfo
+ if ( ( srcClasses & EPositionInfoClass ) &&
+ ( dstClasses & EPositionInfoClass ) )
+ {
+ TPosition pos;
+ static_cast < const TPositionInfo& > ( aSrc ).GetPosition( pos );
+ static_cast < TPositionInfo& > ( aDst ).SetPosition( pos );
+ }
+
+ //Handle TPositionCourseInfo
+ if ( ( srcClasses & EPositionCourseInfoClass ) &&
+ ( dstClasses & EPositionCourseInfoClass ) )
+ {
+ TCourse course;
+ static_cast < const TPositionCourseInfo& > ( aSrc ).GetCourse( course );
+ static_cast < TPositionCourseInfo& > ( aDst ).SetCourse( course );
+ }
+
+ //Handle TPositionSatelliteInfo
+ if ( ( srcClasses & EPositionSatelliteInfoClass ) &&
+ ( dstClasses & EPositionSatelliteInfoClass ) )
+ {
+ const TPositionSatelliteInfo& srcSat =
+ static_cast < const TPositionSatelliteInfo& > ( aSrc );
+ TPositionSatelliteInfo& dstSat =
+ static_cast < TPositionSatelliteInfo& > ( aDst );
+
+ dstSat.SetSatelliteTime( srcSat.SatelliteTime() );
+ dstSat.SetHorizontalDoP( srcSat.HorizontalDoP() );
+ dstSat.SetTimeDoP( srcSat.TimeDoP() );
+ dstSat.SetVerticalDoP( srcSat.VerticalDoP() );
+
+ dstSat.ClearSatellitesInView();
+ TInt numSatData = srcSat.NumSatellitesInView();
+
+ for ( TInt i = 0; i < numSatData; i++ )
+ {
+ TSatelliteData satData;
+ srcSat.GetSatelliteData( i, satData );
+ err = dstSat.AppendSatelliteData( satData );
+ if ( err != KErrNone )
+ {
+ return KErrNone;
+ }
+ }
+ }
+
+ //Handle HPositionGenericInfo
+ if ( ( srcClasses & EPositionGenericInfoClass ) &&
+ ( dstClasses & EPositionGenericInfoClass ) )
+ {
+ const HPositionGenericInfo& srcGen =
+ static_cast < const HPositionGenericInfo& > ( aSrc );
+ HPositionGenericInfo& dstGen =
+ static_cast < HPositionGenericInfo& > ( aDst );
+
+ err = PosGenericInfoUser::CopyHGenericInfo( srcGen, dstGen );
+ }
+
+ return err;
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CleanupTimeoutCallback
+// ---------------------------------------------------------
+//
+TInt CPosRequestController::CleanupTimeoutCallback( TAny* aAny )
+ {
+ reinterpret_cast< CPosRequestController* > ( aAny ) ->
+ CleanupTimeout();
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CPosRequestController::CleanupTimeout
+// ---------------------------------------------------------
+//
+void CPosRequestController::CleanupTimeout()
+ {
+ //Cleanup all outstanding location requests
+ ClearLocationRequests();
+ iCleanupTimer->Cancel();
+ }
+
+// End of file