locationrequestmgmt/locationserver/src/EPos_CPositionRequest.cpp
changeset 0 9cfd9a3ee49c
child 9 8ffb8a35ea2f
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <e32base.h>
       
    20 #include <lbspositioninfo.h>
       
    21 #include <lbs/epos_cpositioner.h>
       
    22 #include <lbs/epos_cposmodules.h>
       
    23 #include <lbs/epos_mposmodulesobserver.h>
       
    24 #include "lbsdevloggermacros.h"
       
    25 #include "EPos_ServerPanic.h"
       
    26 #include "EPos_Global.h"
       
    27 #include "EPos_CPosCallbackTimer.h"
       
    28 #include "EPos_CPositionRequest.h"
       
    29 #include "epos_cposmodulessettings.h"
       
    30 
       
    31 //TODO Verify
       
    32 #include "EPos_CPosLocMonitorReqHandlerHub.h"
       
    33 
       
    34 
       
    35 
       
    36 // CONSTANTS
       
    37 #ifdef _DEBUG
       
    38 _LIT(KTraceFileName, "EPos_CPositionRequest.cpp");
       
    39 #endif
       
    40 
       
    41 const TInt KParamPositionInfo = 0;
       
    42 
       
    43 // ================= LOCAL FUNCTIONS ========================
       
    44 
       
    45 void CancelTimerCleanup(TAny* aTimer)
       
    46     {
       
    47     (static_cast<CPosCallbackTimer*>(aTimer))->Cancel();
       
    48     }
       
    49 
       
    50 inline TPositionInfoBase& PositionInfoBase(HBufC8* aBuffer)
       
    51     {
       
    52         return reinterpret_cast<TPositionInfoBase&>
       
    53         (const_cast<TUint8&>(*aBuffer->Ptr()));
       
    54     }
       
    55 inline TPositionInfo& PositionInfo(HBufC8* aBuffer)
       
    56     {
       
    57         return reinterpret_cast<TPositionInfo&>
       
    58         (const_cast<TUint8&>(*aBuffer->Ptr()));
       
    59     }
       
    60 
       
    61 // ================= MEMBER FUNCTIONS =======================
       
    62 
       
    63 // C++ default constructor can NOT contain any code, that
       
    64 // might leave.
       
    65 //
       
    66 CPositionRequest::CPositionRequest(
       
    67     CPosModuleSettings& aModuleSettings,
       
    68     CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub,
       
    69     TProxyPositionerConstructParams& aPositionerParams,
       
    70     TBool aIsProxy)
       
    71 :
       
    72     CActive(EPriorityStandard),
       
    73     iRequestPhase(EPosReqInactive),
       
    74     iPositionerParams(aPositionerParams),
       
    75     iHasProxyPositioner(aIsProxy),
       
    76     iLocMonitorReqHandler(aLocMonitorReqHandlerHub),
       
    77     iModuleSettings(aModuleSettings)
       
    78     {
       
    79     CActiveScheduler::Add(this);
       
    80     }
       
    81 
       
    82 // EPOC default constructor can leave.
       
    83 void CPositionRequest::ConstructL()
       
    84     {
       
    85     TCallBack timeoutCallBack(HandleTimeOut, this);
       
    86     iTimeoutTimer = CPosCallbackTimer::NewL(timeoutCallBack);
       
    87 
       
    88     TCallBack trackingCallBack(TrackingCallback, this);
       
    89     iTrackingTimer = CPosCallbackTimer::NewL(trackingCallBack);
       
    90 
       
    91     iModuleSettings.PosModules().GetModuleInfoL(
       
    92         iPositionerParams.iImplementationUid, 
       
    93         iModuleInfo);
       
    94         
       
    95     if (!iModuleInfo.IsAvailable())
       
    96         {
       
    97         User::Leave(KErrNotFound);
       
    98         }
       
    99 
       
   100     LoadPositionerL();
       
   101     }
       
   102 
       
   103 /**
       
   104  * Two-phased constructor.
       
   105  *
       
   106  * @param aModules Location Settings reference
       
   107  * @param aLocMonitorReqHandlerHub The hub for requests to the location monitor.
       
   108  * @param aPositionerParams contruction parameters needed when creating
       
   109  *        positioner.
       
   110  * @param aIsProxy ETrue if aImplementationUid represents a proxy PSY,
       
   111  *        EFalse otherwise.
       
   112  */
       
   113 CPositionRequest* CPositionRequest::NewL(
       
   114     CPosModuleSettings& aModuleSettings,
       
   115     CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub,
       
   116     TProxyPositionerConstructParams& aPositionerParams,
       
   117     TBool aIsProxy)
       
   118     {
       
   119     CPositionRequest* self = new (ELeave) CPositionRequest(
       
   120         aModuleSettings,
       
   121         aLocMonitorReqHandlerHub,
       
   122         aPositionerParams,
       
   123         aIsProxy);
       
   124     CleanupStack::PushL(self);
       
   125     self->ConstructL();
       
   126     CleanupStack::Pop(self);
       
   127     return self;
       
   128     }
       
   129 
       
   130 /**
       
   131  * Destructor.
       
   132  */
       
   133 CPositionRequest::~CPositionRequest()
       
   134     {
       
   135     // Panic client if request is outstanding
       
   136     if (IsActive())
       
   137         {
       
   138         iMessage.Panic(KPosClientFault, EPositionRequestsNotCancelled);
       
   139         }
       
   140     Cancel();
       
   141     if (iTrackingState == EPosTracking)
       
   142         {
       
   143         StopTracking();
       
   144         }
       
   145     delete iTrackingTimer;
       
   146     delete iPositionBuffer;
       
   147     delete iTimeoutTimer;
       
   148     delete iPositioner;
       
   149     }
       
   150 
       
   151 /**
       
   152  * Starts a position request cycle. Should only be called when PSY is 
       
   153  * enabled.
       
   154  * @param aMessage the request message from the client
       
   155  */
       
   156 void CPositionRequest::MakeRequestL(const RMessage2& aMessage)
       
   157     {
       
   158     if (!iModuleInfo.IsAvailable())
       
   159         {
       
   160         User::Leave(KErrNotFound);
       
   161         }
       
   162 
       
   163     __ASSERT_DEBUG(iPositioner, DebugPanic(EPosServerPanicPositionerNotInitialized));
       
   164 
       
   165     iMessage = aMessage; // Store parameter here in case of leave.
       
   166 
       
   167     // Clear previous position data
       
   168     delete iPositionBuffer;
       
   169     iPositionBuffer = NULL;
       
   170 
       
   171     HBufC8* clientBuf = Global::CopyClientBuffer8LC(aMessage, KParamPositionInfo);
       
   172     CleanupStack::Pop(clientBuf);
       
   173     iPositionBuffer = clientBuf;
       
   174 
       
   175     TPositionInfoBase& infoBase = PositionInfoBase(iPositionBuffer);
       
   176     TUint32 classType = infoBase.PositionClassType();
       
   177 
       
   178     TUint32 classesSupported = iModuleInfo.ClassesSupported(EPositionInfoFamily);
       
   179 
       
   180     // Check that classtype is supported and is of type TPositionInfo
       
   181     if ((classType != (classType & classesSupported)) ||
       
   182         !(classType & EPositionInfoClass))
       
   183         {
       
   184         User::Leave(KErrArgument);
       
   185         }
       
   186 
       
   187     // Set ModuleId to KNullId to be able to verify that Id is set by PSY.
       
   188     infoBase.SetModuleId(KNullUid);
       
   189 
       
   190     CleanupStack::PushL(TCleanupItem(CancelTimerCleanup, iTimeoutTimer));
       
   191 
       
   192     // Start timer if necessary
       
   193     if (iTimeOut.Int64() > 0)
       
   194         {
       
   195         LBS_RDEBUG_INFO("CPositionRequest::MakeRequestL() Start Timeout Timer");
       
   196         iTimeoutTimer->StartTimer(iTimeOut);
       
   197         }
       
   198 
       
   199     LBS_RDEBUG_VAR_INT("CPositionRequest::MakeRequestL() iTrackingState", iTrackingState);
       
   200     switch (iTrackingState)
       
   201         {
       
   202         case EPosNoTracking:
       
   203         case EPosFirstTrackingRequest:
       
   204             StartPositionDataRequestPhase();
       
   205             break;
       
   206 
       
   207         case EPosTracking:
       
   208             StartTrackingTimerWaitPhase();
       
   209             break;
       
   210 
       
   211         case EPosStopTracking:
       
   212             // This must have been handled by Cancel or RunL
       
   213         default:
       
   214             DebugPanic(EPosServerPanicTrackingInconsistency);
       
   215         }
       
   216 
       
   217     CleanupStack::Pop(iTimeoutTimer);
       
   218     }
       
   219 
       
   220 /**
       
   221  * Set the TPositionUpdateOptions object.
       
   222  *
       
   223  * When this class is constructed, the TPositionUpdateOptions object
       
   224  * is constructed using default constructor with no parameters.
       
   225  *
       
   226  * @param aOptions The update options from the client.
       
   227  */
       
   228 void CPositionRequest::SetUpdateOptions(
       
   229     const TPositionUpdateOptionsBase& aOptions)
       
   230     {
       
   231     iTimeOut = aOptions.UpdateTimeOut();
       
   232     TTimeIntervalMicroSeconds newInterval = aOptions.UpdateInterval();
       
   233     TTimeIntervalMicroSeconds oldInterval = iTrackingUpdateInterval;
       
   234 
       
   235     if (newInterval != iTrackingUpdateInterval)
       
   236         {
       
   237         iTrackingUpdateInterval = newInterval;
       
   238 
       
   239         if (newInterval == 0) // "stop periodic updates"
       
   240             {
       
   241             switch (iTrackingState)
       
   242                 {
       
   243                 case EPosFirstTrackingRequest:
       
   244                     iTrackingState = EPosNoTracking;
       
   245                     break;
       
   246 
       
   247                 case EPosTracking:
       
   248                     if (!IsActive())
       
   249                         {
       
   250                         // can stop it right now
       
   251                         StopTracking();
       
   252                         }
       
   253                     else
       
   254                         {
       
   255                         // mark to stop later
       
   256                         iTrackingState = EPosStopTracking;
       
   257                         }
       
   258                     break;
       
   259 
       
   260                 case EPosNoTracking:
       
   261                 case EPosStopTracking:
       
   262                     break;
       
   263                 default:
       
   264                     DebugPanic(EPosServerPanicTrackingInconsistency);
       
   265                     break;
       
   266                 }
       
   267             }
       
   268         else if (oldInterval != 0) // "use another update interval"
       
   269             {
       
   270             if (iRequestPhase == EPosReqInactive)
       
   271                 {
       
   272                 TInt err;
       
   273                 TRAP(err, RestartTrackingL());
       
   274                 }
       
   275             else
       
   276                 {
       
   277                 // can't affect outstanding request
       
   278                 // postpone until request is completed
       
   279                 // it will be handled by RunL or DoCancel
       
   280                 // via HandleTrackingStateL
       
   281                 iNewTrackingInterval = ETrue;
       
   282                 }
       
   283             }
       
   284         else
       
   285             {
       
   286             // oldInterval == 0
       
   287             // newInterval != 0
       
   288             // it means - "start periodic updates"
       
   289             iTrackingState = EPosFirstTrackingRequest;
       
   290             }
       
   291         }
       
   292     }
       
   293 
       
   294 /**
       
   295  * Get the TPositionUpdateOptions object.
       
   296  * @param aOptions The TPositionUpdateOptions object.
       
   297  */
       
   298 void CPositionRequest::GetUpdateOptions(
       
   299     TPositionUpdateOptionsBase& aOptions) const
       
   300     {
       
   301     aOptions.SetUpdateTimeOut(iTimeOut);
       
   302     aOptions.SetUpdateInterval(iTrackingUpdateInterval);
       
   303     }
       
   304 
       
   305 /**
       
   306  * Stops current tracking session
       
   307  */
       
   308 void CPositionRequest::NewTrackingSessionIfTracking()
       
   309     {
       
   310     /* Requestor has been changed. Call Privacy Server. */
       
   311     }
       
   312 
       
   313 /**
       
   314  * Called when changes in locations settings occur.
       
   315  * @param aEvent Event information
       
   316  */
       
   317 void CPositionRequest::HandleSettingsChangeL(TPosModulesEvent aEvent)
       
   318     {
       
   319     if (aEvent.iModuleId != iModuleInfo.ModuleId())
       
   320         {
       
   321         return;
       
   322         }
       
   323 
       
   324     switch (aEvent.iType)
       
   325         {
       
   326         case EPosModulesEventAvailabilityChanged:
       
   327         case EPosModulesEventModuleInstalled:
       
   328             iModuleSettings.PosModules().GetModuleInfoL(
       
   329                 iModuleInfo.ModuleId(), 
       
   330                 iModuleInfo);
       
   331             break;
       
   332         case EPosModulesEventModuleRemoved:
       
   333             iModuleInfo.SetIsAvailable(EFalse);
       
   334             break;
       
   335         default:
       
   336             return;
       
   337         }
       
   338 
       
   339     if (!iModuleInfo.IsAvailable())
       
   340         {
       
   341         if (IsActive())
       
   342             {
       
   343             CompleteClient(KErrNotFound);
       
   344             Cancel();
       
   345             }
       
   346 
       
   347         // Unuse positioner and unload it
       
   348         if (iTrackingState == EPosTracking)
       
   349             {
       
   350             StopPsyTracking();
       
   351             }
       
   352         delete iPositioner;
       
   353         iPositioner = NULL;
       
   354         }
       
   355     else if (!iPositioner)
       
   356         {
       
   357         // psy is re-enabled after being disabled
       
   358         LoadPositionerL();
       
   359         if (iTrackingState == EPosTracking)
       
   360             {
       
   361             StartPsyTrackingL();
       
   362             }
       
   363         }
       
   364     else
       
   365         {
       
   366         // shouldn't happen, but if it does, ignore it
       
   367         }
       
   368     }
       
   369 
       
   370 /**
       
   371  * Called when the server class is shutting down.
       
   372  */
       
   373 void CPositionRequest::NotifyServerShutdown()
       
   374     {
       
   375     if (IsActive())
       
   376         {
       
   377         DEBUG_TRACE("CPositionRequest::NotifyServerShutdown() with active request", __LINE__)
       
   378         CompleteClient(KErrServerTerminated);
       
   379         Cancel();
       
   380         }
       
   381 
       
   382     if (iTrackingState == EPosTracking)
       
   383         {
       
   384         StopTracking();
       
   385         }
       
   386     delete iPositioner;
       
   387     iPositioner = NULL;
       
   388     }
       
   389 
       
   390 /**
       
   391  * From CActive
       
   392  */
       
   393 void CPositionRequest::RunL()
       
   394     {
       
   395     LBS_RDEBUG_VAR_INT("CPositionRequest::RunL() iRequestPhase", iRequestPhase);
       
   396     TInt err = iStatus.Int();
       
   397     switch (iRequestPhase)
       
   398         {
       
   399         case EPosReqPositionRequest:
       
   400             {
       
   401             LBS_RDEBUG_INFO("CPositionRequest::RunL() EPosReqPositionRequest");
       
   402             // Position request finished. Cancel timer.
       
   403             iTimeoutTimer->Cancel();
       
   404             iRequestPhase = EPosReqInactive;
       
   405 
       
   406             CompleteRequest(err);
       
   407 
       
   408             HandleTrackingStateL(); // don't care if it leaves
       
   409             break;
       
   410             }
       
   411 
       
   412         case EPosWaitForTracking:
       
   413             StartPositionDataRequestPhase();
       
   414             break;
       
   415 
       
   416         default :
       
   417         	DEBUG_TRACE("CPositionRequest::RunL() panicing", __LINE__)
       
   418             DebugPanic(EPosServerPanicRequestInconsistency);
       
   419         }
       
   420     }
       
   421 
       
   422 /**
       
   423  * From CActive
       
   424  */
       
   425 TInt CPositionRequest::RunError(TInt /*aError*/)
       
   426     {
       
   427     // Happens only if HandleTrackingStateL leaves
       
   428     // which in turn means that StartTrackingL leaved somewhere
       
   429     // As request is already completed, just ignore the error
       
   430     return KErrNone;
       
   431     }
       
   432 
       
   433 /**
       
   434  * From CActive
       
   435  */
       
   436 void CPositionRequest::DoCancel()
       
   437     {
       
   438     LBS_RDEBUG_VAR_INT("CPositionRequest::DoCancel() iRequestPhase", iRequestPhase);
       
   439     iTimeoutTimer->Cancel();
       
   440 
       
   441     switch (iRequestPhase)
       
   442         {
       
   443         case EPosReqPositionRequest:
       
   444             {
       
   445             __ASSERT_DEBUG(iPositioner, DebugPanic(EPosServerPanicPositionerNotInitialized));
       
   446             DEBUG_TRACE("calling CPositioner::CancelNotifyPositionUpdate()", __LINE__)
       
   447             if(iRequestTimedOut)
       
   448             	{
       
   449             	iPositioner->CancelNotifyPositionUpdate(KErrTimedOut);
       
   450             	}
       
   451             else
       
   452             	{
       
   453             	iPositioner->CancelNotifyPositionUpdate();
       
   454             	}
       
   455             break;
       
   456             }
       
   457         case EPosWaitForTracking:
       
   458             CompleteSelf(KErrCancel);
       
   459             break;
       
   460 
       
   461         default:
       
   462         	DEBUG_TRACE("CPositionRequest::DoCancel() panicing", __LINE__)
       
   463             DebugPanic(EPosServerPanicRequestInconsistency);
       
   464         }
       
   465 
       
   466     TInt err;
       
   467     if (iRequestTimedOut)
       
   468         {
       
   469         iRequestTimedOut = EFalse;
       
   470         CompleteClient(KErrTimedOut);
       
   471         TRAP(err, HandleTrackingStateL());
       
   472         }
       
   473     else
       
   474         {
       
   475         CompleteClient(KErrCancel);
       
   476 
       
   477         // Handle Tracking State
       
   478         if (iTrackingState == EPosStopTracking)
       
   479             {
       
   480             StopTracking();
       
   481             }
       
   482         }
       
   483 
       
   484     iRequestPhase = EPosReqInactive;
       
   485     }
       
   486 
       
   487 
       
   488 void CPositionRequest::CompleteSelf(TInt aReason)
       
   489     {
       
   490     TRequestStatus* status = &iStatus;
       
   491     User::RequestComplete(status, aReason);
       
   492     }
       
   493 
       
   494 void CPositionRequest::CompleteClient(TInt aReason)
       
   495     {
       
   496     if (!iMessage.IsNull())
       
   497         {
       
   498 		LBS_RDEBUG_ARGINT("LBS","Client", "RunL", aReason);
       
   499         iMessage.Complete(aReason);
       
   500         }
       
   501     }
       
   502 
       
   503 void CPositionRequest::CompleteRequest(TInt aReason)
       
   504     {
       
   505     // Return fix to the client
       
   506     if (aReason == KErrNone || aReason == KPositionPartialUpdate)
       
   507         {
       
   508         TInt err = PackPositionData();
       
   509         // err - client cannot receive result data
       
   510         CompleteClient((err != KErrNone) ? err : aReason);
       
   511 
       
   512         // Save current fix to LastKnownPosition handler
       
   513         // partial updates are not stored
       
   514         if ( aReason == KErrNone )
       
   515             {
       
   516             SaveAsLastKnownPosition();
       
   517             }
       
   518         }
       
   519     else
       
   520         {
       
   521         CompleteClient(aReason);
       
   522         }
       
   523     }
       
   524 
       
   525 void CPositionRequest::StartPositionDataRequestPhase()
       
   526     {  
       
   527     LBS_RDEBUG_VAR_INT("CPositionRequest::StartPositionDataRequestPhase() iRequestPhase", iRequestPhase);
       
   528     
       
   529     __ASSERT_DEBUG(iPositioner,
       
   530         DebugPanic(EPosServerPanicPositionerNotInitialized));
       
   531 
       
   532     iReqStartTime.UniversalTime();
       
   533 
       
   534     TPositionInfo& info = PositionInfo(iPositionBuffer);
       
   535 
       
   536     // Set datum type to WGS84
       
   537     TPosition position;
       
   538     info.GetPosition(position);
       
   539     position.SetDatum(KPositionDatumWgs84);
       
   540     info.SetPosition(position);
       
   541 
       
   542     TPositionInfoBase& infoBase = reinterpret_cast<TPositionInfoBase&>(info);
       
   543 
       
   544     // issue request to psy
       
   545     DEBUG_TRACE("calling CPositioner::NotifyPositionUpdate()", __LINE__)
       
   546 
       
   547     iStatus = KRequestPending;
       
   548     iPositioner->NotifyPositionUpdate(infoBase, iStatus);
       
   549 
       
   550     iRequestPhase = EPosReqPositionRequest;
       
   551     SetActive();
       
   552     }
       
   553 
       
   554 void CPositionRequest::StartTrackingTimerWaitPhase()
       
   555 {
       
   556 	LBS_RDEBUG_VAR_INT("CPositionRequest::StartTrackingTimerWaitPhase() iRequestPhase", iRequestPhase);
       
   557     iRequestPhase = EPosWaitForTracking;
       
   558     iStatus = KRequestPending;
       
   559     SetActive();
       
   560 }
       
   561 
       
   562 TInt CPositionRequest::PackPositionData()
       
   563     {
       
   564     TPositionInfo& info = PositionInfo(iPositionBuffer);
       
   565 
       
   566     // Verify that ModuleId, set by PSY, is correct if using specific PSY.
       
   567     // If a proxy PSY is used, the proxy is responsible for verifying UID.
       
   568     if (!iHasProxyPositioner &&
       
   569         info.ModuleId() != iPositionerParams.iImplementationUid)
       
   570         {
       
   571         return KErrGeneral;
       
   572         }
       
   573 
       
   574     // Check that datum type still is WGS84
       
   575     TPosition position;
       
   576     info.GetPosition(position);
       
   577     if (position.Datum() != KPositionDatumWgs84)
       
   578         {
       
   579         return KErrNotSupported;
       
   580         }
       
   581 
       
   582     TPtr8 ptrToBuffer = iPositionBuffer->Des();
       
   583     return Global::Write(iMessage, KParamPositionInfo, ptrToBuffer);
       
   584     }
       
   585 
       
   586 void CPositionRequest::SaveAsLastKnownPosition()
       
   587     {
       
   588     TPosition pos;
       
   589     TPositionInfo& positionInfo = PositionInfo(iPositionBuffer);
       
   590     positionInfo.GetPosition(pos);
       
   591 
       
   592     // Don't set last known position if the position request is in the past. //TODO check if this is required
       
   593     if (iReqStartTime <= pos.Time())
       
   594         {
       
   595         iLocMonitorReqHandler.SetPositionInfo(positionInfo);
       
   596         }
       
   597     }
       
   598 
       
   599 TInt CPositionRequest::HandleTimeOut(TAny* aPositionRequest)
       
   600     {
       
   601     CPositionRequest* self =
       
   602         reinterpret_cast<CPositionRequest*>(aPositionRequest);
       
   603     
       
   604     LBS_RDEBUG_VAR_INT("CPositionRequest::HandleTimeOut() iRequestPhase", self->iRequestPhase);
       
   605     DEBUG_TRACE("CPositionRequest::HandleTimeOut()", __LINE__)    
       
   606     __ASSERT_DEBUG(self->iRequestPhase == EPosReqPositionRequest || self->iRequestPhase == EPosWaitForTracking,
       
   607         DebugPanic(EPosServerPanicRequestInconsistency));
       
   608 
       
   609     self->iRequestTimedOut = ETrue;
       
   610     self->Cancel();
       
   611 
       
   612     return KErrNone;
       
   613     }
       
   614 
       
   615 TInt CPositionRequest::TrackingCallback(TAny* aPositionRequest)
       
   616     {
       
   617     CPositionRequest* self =
       
   618         reinterpret_cast<CPositionRequest*>(aPositionRequest);
       
   619 
       
   620     // continue tracking timer
       
   621     if (self->iTrackingState == EPosTracking)
       
   622         {
       
   623         self->ContinueTrackingTimer();
       
   624         }
       
   625 
       
   626     if (self->iRequestPhase == EPosWaitForTracking)
       
   627         {
       
   628         // This is the normal case. The client's request was delayed
       
   629         // by the update interval.
       
   630         // Complete tracking timer waiting and go next stage
       
   631         self->CompleteSelf(KErrNone);
       
   632         }
       
   633 
       
   634     return KErrNone;
       
   635     }
       
   636 
       
   637 void CPositionRequest::HandleTrackingStateL()
       
   638     {
       
   639     switch (iTrackingState)
       
   640         {
       
   641         case EPosNoTracking:
       
   642             break;
       
   643 
       
   644         case EPosFirstTrackingRequest:
       
   645             // start internal tracking
       
   646             iTrackingState = EPosTracking;
       
   647             ContinueTrackingTimer();
       
   648 
       
   649             StartPsyTrackingL();
       
   650             break;
       
   651 
       
   652         case EPosTracking:
       
   653             // if tracking interval was changed
       
   654             if (iNewTrackingInterval)
       
   655                 {
       
   656                 RestartTrackingL();
       
   657                 }
       
   658             break;
       
   659 
       
   660         case EPosStopTracking:
       
   661             StopTracking();
       
   662             break;
       
   663 
       
   664         default:
       
   665             DebugPanic(EPosServerPanicTrackingInconsistency);
       
   666         }
       
   667     }
       
   668 
       
   669 void CPositionRequest::StartPsyTrackingL()
       
   670     {
       
   671     __ASSERT_DEBUG(iPositioner, DebugPanic(EPosServerPanicPositionerNotInitialized));
       
   672 
       
   673     iNewTrackingInterval = EFalse;
       
   674 
       
   675     DEBUG_TRACE("calling CPositioner::TrackingOverridden()", __LINE__)
       
   676     if (iPositioner->TrackingOverridden())
       
   677         {
       
   678         DEBUG_TRACE("calling CPositioner::StartTrackingL()", __LINE__)
       
   679         iPositioner->StartTrackingL(iTrackingUpdateInterval);
       
   680         iPositionerTrackingStarted = ETrue;
       
   681         }
       
   682     }
       
   683 
       
   684 void CPositionRequest::RestartTrackingL()
       
   685     {
       
   686     LBS_RDEBUG_INFO("CPositionRequest::RestartTrackingL()");
       
   687     iTrackingTimer->Cancel();
       
   688     StopPsyTracking();
       
   689     ContinueTrackingTimer();
       
   690     StartPsyTrackingL();
       
   691     }
       
   692 
       
   693 void CPositionRequest::StopTracking()
       
   694     {
       
   695     LBS_RDEBUG_INFO("CPositionRequest::StopTracking()");
       
   696     iTrackingTimer->Cancel();
       
   697     iTrackingState = EPosNoTracking;
       
   698 
       
   699     StopPsyTracking();
       
   700     }
       
   701 
       
   702 void CPositionRequest::StopPsyTracking()
       
   703     {
       
   704     if (iPositioner && iPositionerTrackingStarted)
       
   705         {
       
   706         DEBUG_TRACE("calling CPositioner::StopTracking()", __LINE__)
       
   707         iPositioner->StopTracking();
       
   708         iPositionerTrackingStarted = EFalse;
       
   709         }
       
   710     }
       
   711 
       
   712 void CPositionRequest::ContinueTrackingTimer()
       
   713     {
       
   714     LBS_RDEBUG_INFO("CPositionRequest::ContinueTrackingTimer()");
       
   715     iTrackingTimer->StartTimer(iTrackingUpdateInterval);
       
   716     }
       
   717 
       
   718 void CPositionRequest::LoadPositionerL()
       
   719     {
       
   720     iPositioner = CPositioner::NewL(&iPositionerParams);
       
   721     iPositionerTrackingStarted = EFalse;
       
   722     }
       
   723 
       
   724 void CPositionRequest::ExtendUpdateTimeOut(const TTimeIntervalMicroSeconds& aAdditionalTime)
       
   725 	{
       
   726 	LBS_RDEBUG_INFO("CPositionRequest::ExtendUpdateTimeOut()");
       
   727 	iTimeoutTimer->ExtendTimeout(aAdditionalTime);
       
   728 	}
       
   729 
       
   730 //  End of File