datasourcemodules/defaultpositioningmodule/src/EPos_CPosRequestController.cpp
changeset 0 9cfd9a3ee49c
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2007-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 <ecom/ecom.h>
       
    20 
       
    21 #include <lbscommon.h>
       
    22 #include <lbspositioninfo.h>
       
    23 #include <lbs/epos_cposmodules.h>
       
    24 #include <lbs/epos_cposmoduleidlist.h>
       
    25 #include <lbs/epos_cpositioner.h>
       
    26 #include <lbssatellite.h>
       
    27 #include "epos_mposmodulestatusmanager.h"
       
    28 
       
    29 #include "EPos_CPosRequestController.h"
       
    30 #include "epos_cposrequestor.h"
       
    31 #include "epos_defaultproxycommon.h"
       
    32 #include "epos_cpospsylisthandler.h"
       
    33 #include "epos_cpospsyfixstatemanager.h"
       
    34 #include "epos_cposconstmanager.h"
       
    35 #include "epos_cposexternalgpsmonitor.h"
       
    36 #include "epos_posgenericinfouser.h"
       
    37 
       
    38 
       
    39 // ================= LOCAL FUNCTIONS =======================
       
    40 
       
    41 // ================= MEMBER FUNCTIONS =======================
       
    42 
       
    43 // C++ default constructor can NOT contain any code, that
       
    44 // might leave.
       
    45 //
       
    46 CPosRequestController::CPosRequestController(
       
    47     CPosDefaultPositioner& aDefaultPositioner, 
       
    48     MPosModuleStatusManager& aModuleStatusManager)
       
    49     :
       
    50     iDefaultPositioner( aDefaultPositioner ),
       
    51     iModuleStatusManager( aModuleStatusManager ),
       
    52     iCurrentPsy( KErrNotFound )
       
    53     {
       
    54     }
       
    55 
       
    56 // EPOC default constructor can leave.
       
    57 void CPosRequestController::ConstructL(
       
    58         MPosModuleSettingsManager& aSettingsManager )
       
    59     {
       
    60     TRACESTRING( "CPosRequestController::ConstructL start... " )
       
    61     
       
    62     iPsyListHandler = CPosPsyListHandler::GetInstanceL();
       
    63     iPsyListHandler->SetModuleSettingsManagerL( 
       
    64         aSettingsManager );
       
    65     iPsyListHandler->AddListenerL( this );
       
    66 
       
    67     
       
    68     iPsyFixStateManager = CPosPsyFixStateManager::GetInstanceL();
       
    69     iPsyFixStateManager->AddListenerL( this );
       
    70     iConstManager = CPosConstManager::GetInstanceL();
       
    71 
       
    72     iExtGpsPsyMonitor = CPosExternalGpsMonitor::GetInstanceL( 
       
    73         iDefaultPositioner,
       
    74         iModuleStatusManager );
       
    75 
       
    76     //Construct cleanup timer
       
    77     iCleanupTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
    78 
       
    79     TRACESTRING( "CPosRequestController::ConstructL end " )
       
    80     
       
    81     }
       
    82 
       
    83 // Two-phased constructor.
       
    84 CPosRequestController* CPosRequestController::NewL(
       
    85     CPosDefaultPositioner& aDefaultPositioner,
       
    86     MPosModuleSettingsManager& aSettingsManager,
       
    87     MPosModuleStatusManager& aModuleStatusManager )
       
    88     {
       
    89     CPosRequestController* self = new (ELeave)
       
    90         CPosRequestController(
       
    91             aDefaultPositioner,
       
    92             aModuleStatusManager );
       
    93 
       
    94     CleanupStack::PushL(self);
       
    95     self->ConstructL( 
       
    96         aSettingsManager );
       
    97     CleanupStack::Pop(self);
       
    98     return self;
       
    99     }
       
   100 
       
   101 // Destructor
       
   102 CPosRequestController::~CPosRequestController()
       
   103     {
       
   104     TRACESTRING( "CPosRequestController::destructor start... " )
       
   105     
       
   106     if ( iPsyFixStateManager )
       
   107         {
       
   108         iPsyFixStateManager->RemoveListener( this );
       
   109         iPsyFixStateManager->ReleaseInstance();
       
   110         }
       
   111     
       
   112     if ( iPsyListHandler )
       
   113         {
       
   114         iPsyListHandler->RemoveListener( this );
       
   115         iPsyListHandler->ReleaseInstance();
       
   116         }
       
   117         
       
   118     if ( iConstManager )
       
   119         {
       
   120         iConstManager->ReleaseInstance();
       
   121         }
       
   122         
       
   123     if ( iExtGpsPsyMonitor )
       
   124         {
       
   125         iExtGpsPsyMonitor->ReleaseInstance(
       
   126             iDefaultPositioner );
       
   127         }
       
   128 
       
   129     // Close all requestors 
       
   130     iRequestorArray.ResetAndDestroy();
       
   131     iRequestorArray.Close();
       
   132     
       
   133     //Close PSY List
       
   134     iPsyList.Close();
       
   135     
       
   136     // Cleanup timer
       
   137     delete iCleanupTimer;
       
   138 
       
   139     TRACESTRING( "CPosRequestController::destructor end... " )
       
   140 
       
   141     }
       
   142 
       
   143 // ---------------------------------------------------------
       
   144 // CPosRequestController::NotifyPositionUpdate
       
   145 // ---------------------------------------------------------
       
   146 //
       
   147 void CPosRequestController::NotifyPositionUpdate(
       
   148     TPositionInfoBase& aPosInfo,
       
   149     TRequestStatus& aStatus)
       
   150     {
       
   151     TRACESTRING( "CPosRequestController::NotifyPositionUpdate start... " )
       
   152 
       
   153     //Default Proxy can't handle simultaneous location request.
       
   154     __ASSERT_DEBUG( 
       
   155         iPosRequestStatus == NULL, 
       
   156         DefaultProxyPanic( EDefaultProxyPanic_SimualtaneousLR ) );
       
   157     
       
   158     aStatus = KRequestPending;
       
   159     iPosRequestStatus = &aStatus;
       
   160     iPosInfo = &aPosInfo;
       
   161     
       
   162     //When location request received, clear cleanup timer
       
   163     iCleanupTimer->Cancel();
       
   164     
       
   165     TRAPD( err, StartPositionUpdateL() );
       
   166     if( err != KErrNone )
       
   167         {
       
   168         CompleteRequest(err);
       
   169         }
       
   170 
       
   171     TRACESTRING( "CPosRequestController::NotifyPositionUpdate end " )
       
   172     }
       
   173 
       
   174 // ---------------------------------------------------------
       
   175 // CPosRequestController::CancelNotifyPositionUpdate
       
   176 // ---------------------------------------------------------
       
   177 //
       
   178 void CPosRequestController::CancelNotifyPositionUpdate(TInt aCancelReason)
       
   179     {
       
   180     TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) start... " )
       
   181 
       
   182     //Cancel location request with error to all loaded requestor
       
   183     TInt loadedRequestorCount = iRequestorArray.Count();
       
   184     for ( TInt i = 0; i < loadedRequestorCount; i++ )
       
   185         {
       
   186         CancelRequest( i, aCancelReason );
       
   187         }
       
   188         
       
   189     CompleteRequest(KErrCancel);
       
   190 
       
   191     TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate(TInt) end " )
       
   192     }
       
   193 
       
   194 // ---------------------------------------------------------
       
   195 // CPosRequestController::CancelNotifyPositionUpdate
       
   196 // ---------------------------------------------------------
       
   197 //
       
   198 void CPosRequestController::CancelNotifyPositionUpdate()
       
   199     {
       
   200     TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate start... " )
       
   201 
       
   202     // This is a real user cancel
       
   203     CancelNotifyPositionUpdate(KErrCancel);
       
   204     
       
   205     TRACESTRING( "CPosRequestController::CancelNotifyPositionUpdate end " )
       
   206     }
       
   207 
       
   208 // ---------------------------------------------------------
       
   209 // CPosRequestController::CancelRequest
       
   210 // ---------------------------------------------------------
       
   211 //
       
   212 void CPosRequestController::CancelRequest( TInt aIndex, TInt aCancelReason )
       
   213     {
       
   214     TInt count = iRequestorArray.Count();
       
   215     if ( aIndex < count )
       
   216         {
       
   217         CPosRequestor* requestor = iRequestorArray[aIndex];
       
   218         if ( requestor->IsActive() )
       
   219             {
       
   220             //Notify external GPS PSY monitor that this PSY is not used.
       
   221             iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() );
       
   222             requestor->CancelWithReason(aCancelReason);
       
   223             }
       
   224         }
       
   225     }
       
   226 
       
   227 // ---------------------------------------------------------
       
   228 // CPosRequestController::CancelRequest
       
   229 // ---------------------------------------------------------
       
   230 //
       
   231 void CPosRequestController::CancelRequest( TPositionModuleId aPsyId )
       
   232     {
       
   233     TInt count = iRequestorArray.Count();
       
   234     for ( TInt i = 0; i < count; i++ )
       
   235         {
       
   236         CPosRequestor* requestor = iRequestorArray[i];
       
   237         if ( requestor->ModuleId() == aPsyId && 
       
   238             requestor->IsActive() )
       
   239             {
       
   240             //Notify external GPS PSY monitor that this PSY is not used.
       
   241             iExtGpsPsyMonitor->PsyNotUsed( requestor->ModuleId() );
       
   242             requestor->Cancel();
       
   243             }
       
   244         }
       
   245     }
       
   246 
       
   247 // ---------------------------------------------------------
       
   248 // CPosRequestController::StartTrackingL
       
   249 // ---------------------------------------------------------
       
   250 //
       
   251 void CPosRequestController::StartTracking(
       
   252     const TTimeIntervalMicroSeconds& /*aInterval*/)
       
   253     {
       
   254     //This function does nothing. Tracking will be started
       
   255     //to any specific PSY only if this PSY will be used by
       
   256     //Default Proxy. 
       
   257 
       
   258     TRACESTRING( "CPosRequestController::StartTracking" )
       
   259 
       
   260     }
       
   261 
       
   262 // ---------------------------------------------------------
       
   263 // CPosRequestController::StopTracking
       
   264 // ---------------------------------------------------------
       
   265 //
       
   266 void CPosRequestController::StopTracking()
       
   267     {
       
   268     TRACESTRING( "CPosRequestController::StopTracking start..." )
       
   269     
       
   270     //Stop tracking to all loaded PSYs
       
   271     TInt loadedRequestorCount = iRequestorArray.Count();
       
   272     for ( TInt i = 0; i < loadedRequestorCount; i++ )
       
   273         {
       
   274         iRequestorArray[i]->StopTracking();
       
   275         }
       
   276 
       
   277     TRACESTRING( "CPosRequestController::StopTracking end" )
       
   278 
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------
       
   282 // CPosRequestController::StartPositionUpdateL
       
   283 // ---------------------------------------------------------
       
   284 //
       
   285 void CPosRequestController::StartPositionUpdateL()
       
   286     {
       
   287     TRACESTRING( "CPosRequestController::StartPositionUpdateL start..." )
       
   288 
       
   289     //Rebuid PSY list if neccessary
       
   290     if ( !iPsyListValid )
       
   291         {
       
   292         iPsyListHandler->GetPsyListL( iPsyList );
       
   293         iPsyListValid = ETrue;
       
   294         }
       
   295         
       
   296     iFirstResult = KErrNotFound;    // as if no enabled psys found
       
   297     iCurrentPsy = KErrNotFound;     // start from first module
       
   298     TryNextPositioner();
       
   299     
       
   300     if ( !IsLocationRequestOnGoing() )
       
   301         {
       
   302         CompleteRequest( iFirstResult );
       
   303         }
       
   304 
       
   305     TRACESTRING( "CPosRequestController::StartPositionUpdateL end" )
       
   306 
       
   307     }
       
   308 
       
   309 
       
   310 // ---------------------------------------------------------
       
   311 // CPosRequestController::TryNextPositioner
       
   312 // ---------------------------------------------------------
       
   313 //
       
   314 void CPosRequestController::TryNextPositioner()
       
   315 {
       
   316     TRACESTRING( "CPosRequestController::TryNextPositioner start..." )
       
   317 
       
   318     // Find next enabled plugin we should try with
       
   319     TInt count = iPsyList.Count();
       
   320     while ( ++iCurrentPsy < count )
       
   321         {
       
   322         TPositionModuleId currentPsyId = iPsyList[iCurrentPsy];
       
   323         
       
   324         TRACESTRING2( "PSY: %x", currentPsyId )
       
   325 
       
   326         TUint32 classType = iPosInfo->PositionClassType();
       
   327         if ( !iPsyListHandler->IsClassSupported( 
       
   328             classType,
       
   329             currentPsyId ) )
       
   330             {
       
   331             //if the requested class is not supported, then we try next PSY
       
   332             //in the PSY list
       
   333             
       
   334             if ( iCurrentPsy == 0 )
       
   335                 {
       
   336                 //Error code fromt the first PSY
       
   337                 iFirstResult = KErrArgument;
       
   338                 }
       
   339 
       
   340             continue;
       
   341             }
       
   342             
       
   343         TRAPD( err, TryPositionerL( currentPsyId ) );
       
   344         
       
   345         TRACESTRING2( "Try PSY completion code = %d", err )
       
   346 
       
   347         if( err == KErrNone )
       
   348             {
       
   349             //Location request is made to currentPsy. Check the fix state of
       
   350             //current PSY, if current PSY can't give a fix, we load next PSY
       
   351             if ( iPsyFixStateManager->GetPsyFixState( currentPsyId ) 
       
   352                 != CPosPsyFixStateManager::EPsyFixStateNo )
       
   353                 {
       
   354                 //break from here. Othsewise, try next PSY
       
   355                 break;
       
   356                 }
       
   357             }
       
   358         else
       
   359             {
       
   360             //In error case, we store the error code if needed and try next PSY
       
   361             if ( iCurrentPsy == 0 )
       
   362                 {
       
   363                 //Error code fromt the first PSY
       
   364                 iFirstResult = err;
       
   365                 }
       
   366             }
       
   367         }
       
   368 
       
   369     TRACESTRING( "CPosRequestController::TryNextPositioner end" )
       
   370 
       
   371 }
       
   372 
       
   373 // ---------------------------------------------------------
       
   374 // CPosRequestController::TryPositionerL
       
   375 // ---------------------------------------------------------
       
   376 //
       
   377 void CPosRequestController::TryPositionerL( TPositionModuleId aPsyId )
       
   378     {
       
   379     CPosRequestor* currentRequestor = NULL;
       
   380     
       
   381     
       
   382     //Check device status of the PSY. If it's in error status,
       
   383     //it will not be used at all.
       
   384     TPositionModuleStatus moduleStatus;
       
   385     iModuleStatusManager.GetModuleStatus( 
       
   386         aPsyId,
       
   387         moduleStatus );
       
   388     if ( moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceError )
       
   389         {
       
   390         TRACESTRING2( "PSY %x device error", aPsyId )
       
   391 
       
   392         User::Leave( KErrGeneral );
       
   393         }
       
   394     
       
   395     //Find if the PSY is already loaded
       
   396     TInt requestorCount = iRequestorArray.Count();
       
   397     for ( TInt i = 0; i < requestorCount; i++ )
       
   398         {
       
   399         if ( iRequestorArray[i]->ModuleId() == aPsyId )
       
   400             {
       
   401             currentRequestor = iRequestorArray[i];
       
   402             break;
       
   403             }
       
   404         }
       
   405     
       
   406     if ( currentRequestor == NULL )
       
   407         {
       
   408         //PSY has not been loaded before, load it now
       
   409         TRACESTRING2( "Loading Positioner: %x", aPsyId )
       
   410         currentRequestor = 
       
   411             CPosRequestor::NewL(
       
   412                 iDefaultPositioner,
       
   413                 aPsyId,
       
   414                 *this,
       
   415                 *iPsyFixStateManager,
       
   416                 iModuleStatusManager );
       
   417                 
       
   418         CleanupStack::PushL( currentRequestor );
       
   419         
       
   420         //Notify fix state manager that a PSY is loaded
       
   421         iPsyFixStateManager->PsyLoadedL( aPsyId );
       
   422         
       
   423         //Add this requestor to requestor array
       
   424         User::LeaveIfError( iRequestorArray.Append( 
       
   425             currentRequestor ) );
       
   426         CleanupStack::Pop( currentRequestor );
       
   427         }
       
   428         
       
   429     //Start tracking if needed
       
   430     TTimeIntervalMicroSeconds interval = iDefaultPositioner.TrackingInterval();
       
   431     if (interval.Int64() != 0 )
       
   432         {
       
   433         currentRequestor->StartTrackingL( interval );
       
   434         }
       
   435     
       
   436     //Make location request to current positioner
       
   437     currentRequestor->MakeLocationRequestL( *iPosInfo );
       
   438     
       
   439     //Notify external GPS PSY monitor that a PSY is used
       
   440     iExtGpsPsyMonitor->PsyUsed( aPsyId );
       
   441     }
       
   442 
       
   443 // ---------------------------------------------------------
       
   444 // CPosRequestController::LocationRequestCompleted
       
   445 // ---------------------------------------------------------
       
   446 //
       
   447 void CPosRequestController::LocationRequestCompleted( 
       
   448             TPositionModuleId aModuleId,
       
   449             TInt aErr,
       
   450             const TPositionInfoBase& aPosInfo,
       
   451             TBool aIsPosInfoUpToDate )
       
   452     {
       
   453     TRACESTRING( "CPosRequestController::LocationRequestCompleted start..." )
       
   454     TRACESTRING2( "PSY: %x", aModuleId )
       
   455     TRACESTRING2( "Err: %d", aErr )
       
   456     TRACESTRING2( "Is PosInfo Updated: %d", aIsPosInfoUpToDate )
       
   457 
       
   458     //Notify the external GPS PSY monitor that a PSY in not used
       
   459     iExtGpsPsyMonitor->PsyNotUsed( aModuleId );
       
   460 
       
   461     TInt err = aErr;
       
   462     if ( aErr == KPositionPartialUpdate && IsLocationRequestOnGoingOnNetworkPsy() )
       
   463         {
       
   464         //Partial update is returned when Network PSY is used.
       
   465         //partial update is not forwarded to system. Instead, location
       
   466         //request is made to the loaded PSY again.
       
   467         TInt ignore;
       
   468         TRAP( ignore, TryPositionerL( aModuleId ) );
       
   469         }
       
   470     else if ( aErr == KErrNone || 
       
   471         aErr == KErrPositionBufferOverflow ||
       
   472         aErr == KPositionPartialUpdate  )
       
   473         {
       
   474         //Location request succeed or
       
   475         //buffer over flow is returned from a PSY or
       
   476         //partial update is returned when only GPS PSY is used
       
   477         
       
   478         //Copy request info, and complete LR
       
   479         if ( aIsPosInfoUpToDate )
       
   480             {
       
   481             __ASSERT_DEBUG( 
       
   482                 aPosInfo.PositionClassSize() == iPosInfo->PositionClassSize(),
       
   483                 DefaultProxyPanic( EDefaultProxyPanic_PosInfoSizeMismatch ) );
       
   484             
       
   485             Mem::Copy( iPosInfo, &aPosInfo, iPosInfo->PositionClassSize() );
       
   486             }
       
   487         else
       
   488             {
       
   489             TInt cpErr = CopyPosInfoClass( aPosInfo , *iPosInfo );
       
   490             if ( cpErr != KErrNone && err == KErrNone )
       
   491                 {
       
   492                 err = cpErr;
       
   493                 }
       
   494             }
       
   495         
       
   496         if ( iPosInfo->ModuleId() != aModuleId )
       
   497             {
       
   498             err = KErrGeneral;
       
   499             }
       
   500             
       
   501         CompleteRequest( err );
       
   502         }
       
   503     else
       
   504         {
       
   505         if ( aModuleId == iPsyList[0] )
       
   506             {
       
   507             //Store the result from first PSY
       
   508             iFirstResult = aErr;
       
   509             
       
   510             //Store module ID of first positioner
       
   511             iPosInfo->SetModuleId( aModuleId );
       
   512             }
       
   513         }
       
   514         
       
   515     //This will cause the state change notification and generate fallback 
       
   516     //if it's a error case.
       
   517     iPsyFixStateManager->SetPsyFixState( aModuleId, aErr );
       
   518     
       
   519     if ( !IsLocationRequestOnGoing() )
       
   520         {
       
   521         CompleteRequest( iFirstResult );
       
   522         }
       
   523 
       
   524     TRACESTRING( "CPosRequestController::LocationRequestCompleted end" )
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------
       
   528 // CPosRequestController::IsLocationRequestOnGoing
       
   529 // ---------------------------------------------------------
       
   530 //
       
   531 TBool CPosRequestController::IsLocationRequestOnGoing() const
       
   532     {
       
   533     TInt count = iRequestorArray.Count();
       
   534     for ( TInt i=0; i < count; i++ )
       
   535         {
       
   536         const CPosRequestor& requestor = *(iRequestorArray[i]);
       
   537         if ( requestor.IsActive() )
       
   538             {
       
   539             return ETrue;
       
   540             }
       
   541         }
       
   542     return EFalse;
       
   543     }
       
   544 
       
   545 // ---------------------------------------------------------
       
   546 // CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy
       
   547 // ---------------------------------------------------------
       
   548 //
       
   549 TBool CPosRequestController::IsLocationRequestOnGoingOnNetworkPsy() const
       
   550     {
       
   551     TInt count = iRequestorArray.Count();
       
   552     for ( TInt i=0; i < count; i++ )
       
   553         {
       
   554         const CPosRequestor& requestor = *(iRequestorArray[i]);
       
   555         if ( requestor.IsActive() && 
       
   556             iPsyListHandler->IsModuleNetworkBased(
       
   557                 requestor.ModuleId() ) )
       
   558             {
       
   559             return ETrue;
       
   560             }
       
   561         }
       
   562     return EFalse;
       
   563     }
       
   564 
       
   565 // ---------------------------------------------------------
       
   566 // CPosRequestController::PsyFixStateChanged
       
   567 // ---------------------------------------------------------
       
   568 //
       
   569 void CPosRequestController::PsyFixStateChanged( 
       
   570             TPositionModuleId aModuleId,
       
   571             CPosPsyFixStateManager::TPsyFixState aFixState )
       
   572     {
       
   573     TRACESTRING( "CPosRequestController::PsyFixStateChanged start..." )
       
   574     TRACESTRING2( "PSY: %x", aModuleId )
       
   575     TRACESTRING2( "Fix state: %d", aFixState )
       
   576 
       
   577     //If there is location request on going and
       
   578     //current can't give a fix, we try next PSY
       
   579     if( iPosRequestStatus && iCurrentPsy<iPsyList.Count() )
       
   580         {
       
   581         if ( aFixState == CPosPsyFixStateManager::EPsyFixStateNo &&
       
   582             iPsyList[iCurrentPsy] == aModuleId )
       
   583             {
       
   584             TryNextPositioner();
       
   585             }
       
   586         }
       
   587 
       
   588     TRACESTRING( "CPosRequestController::PsyFixStateChanged end" )
       
   589     }
       
   590 
       
   591 // ---------------------------------------------------------
       
   592 // CPosRequestController::CompleteRequest
       
   593 // ---------------------------------------------------------
       
   594 //
       
   595 void CPosRequestController::CompleteRequest(TInt aCompleteCode)
       
   596     {
       
   597     TRACESTRING( "CPosRequestController::CompleteRequest start..." )
       
   598     TRACESTRING2( "Completion code: %d", aCompleteCode )
       
   599     TRACESTRING2( "Module Id: %x", iPosInfo->ModuleId() )
       
   600 
       
   601     if (iPosRequestStatus)
       
   602         {
       
   603         User::RequestComplete(iPosRequestStatus, aCompleteCode);
       
   604         iPosRequestStatus = NULL;
       
   605         
       
   606         //Clear all location request if this is not 
       
   607         //a partial update
       
   608         if ( aCompleteCode != KPositionPartialUpdate )
       
   609             {
       
   610             ClearLocationRequests();
       
   611             }
       
   612             
       
   613         //If there is still location request ongoing to other PSYs,
       
   614         //start cleanup timer
       
   615         TInt count = iRequestorArray.Count();
       
   616         for ( TInt i = 0; i < count; i++ )
       
   617             {
       
   618             if ( iRequestorArray[i]->IsActive() )
       
   619                 {
       
   620                 
       
   621                 if ( !iCleanupTimer->IsActive() )
       
   622                     {
       
   623                     iCleanupTimer->Start(
       
   624                         iConstManager->GetCleanupTimeoutValue().Int64(),
       
   625                         iConstManager->GetCleanupTimeoutValue().Int64(),
       
   626                         TCallBack( CleanupTimeoutCallback, this )
       
   627                         );
       
   628                     }
       
   629                 }
       
   630             }
       
   631         }
       
   632     TRACESTRING( "CPosRequestController::CompleteRequest end" )
       
   633     }
       
   634 
       
   635 // ---------------------------------------------------------
       
   636 // CPosRequestController::ClearLocationRequests
       
   637 // ---------------------------------------------------------
       
   638 //
       
   639 void CPosRequestController::ClearLocationRequests()
       
   640     {
       
   641     TInt count = iRequestorArray.Count();
       
   642     for ( TInt i = 0; i < count; i++ )
       
   643         {
       
   644         CancelRequest( i, KErrCancel);
       
   645         }
       
   646     }
       
   647 
       
   648 // ---------------------------------------------------------
       
   649 // CPosRequestController::PsyListChanged
       
   650 // ---------------------------------------------------------
       
   651 //
       
   652 void CPosRequestController::PsyListChanged( 
       
   653             const TPosPsyListChangeEvent& aEvent )
       
   654     {
       
   655     TRACESTRING( "CPosRequestController::PsyListChanged start..." )
       
   656     TRACESTRING2( "Event type: %d", aEvent.iType )
       
   657     TRACESTRING2( "PSY: %x", aEvent.iPsyId )
       
   658     
       
   659     switch ( aEvent.iType )
       
   660         {
       
   661         case EPosPsyListChangeEventPsyDeleted:
       
   662             {
       
   663             //Cancel location request to this PSY
       
   664             CancelRequest( aEvent.iPsyId );
       
   665                     
       
   666             if ( iCurrentPsy >= 0 && iCurrentPsy < iPsyList.Count() )
       
   667                 {
       
   668                 //If there is location request on going
       
   669                 if ( aEvent.iPsyId == iPsyList[iCurrentPsy] )
       
   670                     {
       
   671                     //fallback to next PSY
       
   672                     TryNextPositioner();
       
   673                     }
       
   674                 }
       
   675             //Delete this PSY from the list
       
   676             TInt index = iPsyList.Find( aEvent.iPsyId );
       
   677             if ( index != KErrNotFound )
       
   678                 {
       
   679                 iPsyList.Remove( index );
       
   680                 }
       
   681                 
       
   682             //Unload this PSY
       
   683             UnloadRequestor( aEvent.iPsyId );
       
   684             }
       
   685             break;
       
   686         case EPosPsyListChangeEventListRebuild:
       
   687         default:
       
   688             //Rebuild the list
       
   689             iPsyListValid = EFalse;
       
   690             break;
       
   691         }
       
   692 
       
   693     TRACESTRING( "CPosRequestController::PsyListChanged end" )
       
   694     }
       
   695 
       
   696 
       
   697 // ---------------------------------------------------------
       
   698 // CPosRequestController::GetRequestor
       
   699 // ---------------------------------------------------------
       
   700 //
       
   701 CPosRequestor* CPosRequestController::GetRequestor(
       
   702             TPositionModuleId aPsyId )
       
   703     {
       
   704     TInt count = iRequestorArray.Count();
       
   705     for ( TInt i = 0; i < count; i++ )
       
   706         {
       
   707         if ( iRequestorArray[i]->ModuleId() == aPsyId )
       
   708             {
       
   709             return iRequestorArray[i];
       
   710             }
       
   711         }
       
   712     return NULL;
       
   713     }
       
   714 
       
   715 // ---------------------------------------------------------
       
   716 // CPosRequestController::UnloadRequestor
       
   717 // ---------------------------------------------------------
       
   718 //
       
   719 void CPosRequestController::UnloadRequestor( TPositionModuleId aPsyId )
       
   720     {
       
   721     TRACESTRING( "CPosRequestController::UnloadRequestor" )
       
   722     TRACESTRING2( "PSY: %x", aPsyId )
       
   723 
       
   724     TInt count = iRequestorArray.Count();
       
   725     for ( TInt i = count-1; i >= 0; i-- )
       
   726         {
       
   727         if ( iRequestorArray[i]->ModuleId() == aPsyId )
       
   728             {
       
   729             delete iRequestorArray[i];
       
   730             iRequestorArray.Remove( i );
       
   731             }
       
   732         }
       
   733     }
       
   734 
       
   735 // ---------------------------------------------------------
       
   736 // CPosRequestController::CopyPosInfoClass
       
   737 // ---------------------------------------------------------
       
   738 //
       
   739 TInt CPosRequestController::CopyPosInfoClass(
       
   740             const TPositionInfoBase& aSrc,
       
   741             TPositionInfoBase& aDst )
       
   742     {
       
   743     TInt err = KErrNone;
       
   744     
       
   745     TUint32 srcClasses = aSrc.PositionClassType();
       
   746     TUint32 dstClasses = aDst.PositionClassType();
       
   747     
       
   748     //Handle TPositionInfoBase
       
   749     aDst.SetModuleId( aSrc.ModuleId() );
       
   750     aDst.SetUpdateType( aSrc.UpdateType() );
       
   751     
       
   752     //Handle TPositionInfo
       
   753     if ( ( srcClasses & EPositionInfoClass ) &&
       
   754         ( dstClasses & EPositionInfoClass ) )
       
   755         {
       
   756         TPosition pos;
       
   757         static_cast < const TPositionInfo& > ( aSrc ).GetPosition( pos );
       
   758         static_cast < TPositionInfo& > ( aDst ).SetPosition( pos );
       
   759         }
       
   760         
       
   761     //Handle TPositionCourseInfo
       
   762     if ( ( srcClasses & EPositionCourseInfoClass ) &&
       
   763         ( dstClasses & EPositionCourseInfoClass ) )
       
   764         {
       
   765         TCourse course;
       
   766         static_cast < const TPositionCourseInfo& > ( aSrc ).GetCourse( course );
       
   767         static_cast < TPositionCourseInfo& > ( aDst ).SetCourse( course );
       
   768         }
       
   769         
       
   770     //Handle TPositionSatelliteInfo
       
   771     if ( ( srcClasses & EPositionSatelliteInfoClass ) &&
       
   772         ( dstClasses & EPositionSatelliteInfoClass ) )
       
   773         {
       
   774         const TPositionSatelliteInfo& srcSat = 
       
   775             static_cast < const TPositionSatelliteInfo& > ( aSrc );
       
   776         TPositionSatelliteInfo& dstSat = 
       
   777             static_cast < TPositionSatelliteInfo& > ( aDst );
       
   778 
       
   779         dstSat.SetSatelliteTime( srcSat.SatelliteTime() );
       
   780         dstSat.SetHorizontalDoP( srcSat.HorizontalDoP() );
       
   781         dstSat.SetTimeDoP( srcSat.TimeDoP() );
       
   782         dstSat.SetVerticalDoP( srcSat.VerticalDoP() );
       
   783         
       
   784         dstSat.ClearSatellitesInView();
       
   785         TInt numSatData = srcSat.NumSatellitesInView();
       
   786         
       
   787         for ( TInt i = 0; i < numSatData; i++ )
       
   788             {
       
   789             TSatelliteData satData;
       
   790             srcSat.GetSatelliteData( i, satData );
       
   791             err = dstSat.AppendSatelliteData( satData );
       
   792             if ( err != KErrNone )
       
   793                 {
       
   794                 return KErrNone;
       
   795                 }
       
   796             }
       
   797         }
       
   798         
       
   799     //Handle HPositionGenericInfo
       
   800     if ( ( srcClasses & EPositionGenericInfoClass ) &&
       
   801         ( dstClasses & EPositionGenericInfoClass ) )
       
   802         {
       
   803         const HPositionGenericInfo& srcGen = 
       
   804             static_cast < const HPositionGenericInfo& > ( aSrc );
       
   805         HPositionGenericInfo& dstGen = 
       
   806             static_cast < HPositionGenericInfo& > ( aDst );
       
   807         
       
   808         err = PosGenericInfoUser::CopyHGenericInfo( srcGen, dstGen );
       
   809         }
       
   810     
       
   811     return err;
       
   812     }
       
   813 
       
   814 // ---------------------------------------------------------
       
   815 // CPosRequestController::CleanupTimeoutCallback
       
   816 // ---------------------------------------------------------
       
   817 //
       
   818 TInt CPosRequestController::CleanupTimeoutCallback( TAny* aAny )
       
   819     {
       
   820     reinterpret_cast< CPosRequestController* > ( aAny ) ->
       
   821         CleanupTimeout();
       
   822     return KErrNone;
       
   823     }
       
   824         
       
   825 // ---------------------------------------------------------
       
   826 // CPosRequestController::CleanupTimeout
       
   827 // ---------------------------------------------------------
       
   828 //
       
   829 void CPosRequestController::CleanupTimeout()
       
   830     {
       
   831     //Cleanup all outstanding location requests
       
   832     ClearLocationRequests();
       
   833     iCleanupTimer->Cancel();
       
   834     }
       
   835 
       
   836 // End of file