locationtriggering/ltstrategyengine/src/lbtcoordinatesupervisor.cpp
changeset 56 4e949f03ecc5
equal deleted inserted replaced
-1:000000000000 56:4e949f03ecc5
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of coordinate supervisor class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <e32math.h>
       
    21 #include <e32const.h>
       
    22 #include <lbttriggerconditionarea.h>
       
    23 #include <lbtgeocircle.h>
       
    24 #include "lbtcelliddatabase.h"
       
    25 #include "lbtcellchangehandler.h"
       
    26 #include "lbtlogger.h"
       
    27 #include "lbtcoordinatesupervisor.h"
       
    28 #include "lbtstrategyengineobserver.h"
       
    29 #include "lbtpsychangelistner.h"
       
    30 
       
    31 // ==================== CONSTANTS ===================================
       
    32 
       
    33 /**
       
    34  * Constant used to adjust trigger radius to accomodate inaccuracy 
       
    35  * of position fixes
       
    36  */
       
    37 static const TReal32 KAccuracyMultiplier = 0.666667;
       
    38 
       
    39 /**
       
    40  * The cut off value of the ratio of radius to position accuracy. Over this 
       
    41  * value the radius of a trigger will not be expanded.
       
    42  */
       
    43 static const TReal32 KCofftOfHighEdgeLimit = 1.5;
       
    44 
       
    45 /**
       
    46  * Constant used in calculation of trigger hysteresis
       
    47  */
       
    48 static const TUint16 KTriggerRadiusCutoff = 500;
       
    49 
       
    50 /**
       
    51  *  Contant time use in calculation of speed
       
    52  */
       
    53 static const TReal32 constantTime = 20;
       
    54 
       
    55 /**
       
    56  * Defines the number of historic speed values that will be stored
       
    57  * and used for calculation of current speed
       
    58  */
       
    59 static const TUint16 maxObsValues = 10;
       
    60 
       
    61 /**
       
    62  * Minimum calculated speed. If this calculated speed drops below this value
       
    63  * then the below value is speed as the speed value 
       
    64  */
       
    65 static const TReal KMinProjSpeed = 20.0;
       
    66 
       
    67 static const TReal KMaxSpeedToUseMvmtDet = 5.0;
       
    68 /**
       
    69  * If the estimated sleep interval goes below this value then location request
       
    70  * will be issued immediately with the estimated interval as the time out value
       
    71  * for the location rquest
       
    72  */
       
    73 static const TInt KMinSleepInterval = 2;
       
    74 
       
    75 /**
       
    76  * Multiplier used for 10 power 3. Used for conversion of seconds to micro
       
    77  * seconds
       
    78  */
       
    79 static const TUint KMicroMultiplier = 1000000;
       
    80 
       
    81 /**
       
    82  * Number of seconds to sleep before making location request in cases where 
       
    83  * a location acquisition attempt fails to obtain a fix
       
    84  */
       
    85 static const TUint KSleepTimeOnLocAcqFailure = 10; // 10 seconds
       
    86 
       
    87 /**
       
    88  * Safe range of HA obtained from NPP
       
    89  */
       
    90 //static const TUint KNppSafeHA = 1500; // 1500 meters
       
    91 
       
    92 // ============================== MEMBER FUNCTIONS ============================================
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CLbtCoOrdinateSupervisor::NewL
       
    96 // CLbtCoOrdinateSupervisor instantiation method
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 CLbtCoOrdinateSupervisor* CLbtCoOrdinateSupervisor::NewL( TAny* aConstructionParameters, 
       
   100                                                           CLbtTriggerView* aView,
       
   101                                                           MLbtStrategyEngineObsrvr* aObserver,
       
   102                                                           CLbtCellChangeHandler* aCellChangeHandler )
       
   103     {
       
   104     CLbtCoOrdinateSupervisor* self = new ( ELeave ) CLbtCoOrdinateSupervisor();
       
   105     CleanupStack::PushL( self );
       
   106     self->ConstructL( aConstructionParameters, aView,aObserver,aCellChangeHandler );
       
   107     CleanupStack::Pop();
       
   108     return self;    
       
   109     }
       
   110 
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CLbtCoOrdinateSupervisor::~CLbtCoOrdinateSupervisor
       
   114 // Default destructor
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 CLbtCoOrdinateSupervisor::~CLbtCoOrdinateSupervisor()
       
   118     {
       
   119     // This is just done as a precautionary measure!
       
   120     StopSupervision();
       
   121     delete iLocationRequestor;
       
   122     delete iStatusManager;
       
   123     delete iTimer;
       
   124     delete iPsyChangeListner;
       
   125     delete iCellIdDatabase;
       
   126     iNObservedValues.Close();
       
   127     iNearestTriggers.Close();
       
   128     }	
       
   129 
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // CLbtCoOrdinateSupervisor::StartSupervision
       
   133 // 
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 void CLbtCoOrdinateSupervisor::StartSupervision()
       
   137     {
       
   138     FUNC_ENTER("CLbtCoOrdinateSupervisor::StartSupervision");
       
   139     iCellChangeHandler->SetObserver( this );    
       
   140     RequestTerminalPosition( iSettings.iLocationRequestTimeout );    
       
   141     }
       
   142 
       
   143     
       
   144 // -----------------------------------------------------------------------------
       
   145 // CLbtCoOrdinateSupervisor::StopSupervision
       
   146 // 
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 void CLbtCoOrdinateSupervisor::StopSupervision()
       
   150     {
       
   151     FUNC_ENTER("CLbtCoOrdinateSupervisor::StopSupervision");
       
   152     iCellChangeHandler->Remove( this );
       
   153     Term(); 
       
   154     }
       
   155     
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CLbtCoOrdinateSupervisor::SettingsChanged
       
   159 // Handles notification of triggering settings change provided by server
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 void CLbtCoOrdinateSupervisor::SettingsChanged()
       
   163     {    
       
   164     iEngObserver->RetrieveTriggeringSettings( iSettings );    
       
   165     }
       
   166 
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CLbtCoOrdinateSupervisor::Resume
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 //
       
   173 void CLbtCoOrdinateSupervisor::Resume()
       
   174     {
       
   175     FUNC_ENTER("CLbtCoOrdinateSupervisor::Resume");
       
   176     TInt err = KErrNone;
       
   177     iCellChangeHandler->SetObserver( this );    
       
   178 
       
   179     switch( iProjectedState )
       
   180             {
       
   181         case ELocationAcquisition:
       
   182             iProjectedState = EIdle;
       
   183             RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
   184             break;
       
   185 
       
   186         case ETriggerEvaluation:
       
   187             // Reset trigger iterator and start evaluation of all triggers in
       
   188             // view            
       
   189             iProjectedState = EIdle;
       
   190             err = ResetViewIterator();
       
   191             if( KErrNone != err )
       
   192                 {
       
   193                 return;
       
   194                 }
       
   195             iState = ETriggerEvaluation;
       
   196             SetEvent();
       
   197             break;
       
   198             
       
   199         case EUpdateIntervalEstimation:
       
   200 
       
   201             // Evaluate triggers that have undergone changes during the state
       
   202             // change. This is to determine any new nearest trigger
       
   203             iProjectedState = EIdle;
       
   204 
       
   205 
       
   206             iView->DetermineNearestTriggerChanges( &iNearestTriggers );
       
   207             if( iNearestTriggers.Count() == 0 )
       
   208                 {
       
   209                 // This means all known nearest triggers have been modified. 
       
   210                 // Reset iterator re-evaluate all triggers in the system. 
       
   211                 TInt err = ResetViewIterator();
       
   212                 if( KErrNone != err )
       
   213                     {
       
   214                     return;
       
   215                     }
       
   216                 
       
   217                 iState = ETriggerEvaluation;
       
   218                 SetEvent();
       
   219                 }
       
   220             else
       
   221                 {
       
   222                 // Evaluate only the modified triggers
       
   223                 TBool makeLocReq = EFalse;
       
   224                 TRAP( err, makeLocReq = EvaluateModifiedTriggersL() );
       
   225                 if( KErrNone == err )
       
   226                     {
       
   227                     if( makeLocReq )
       
   228                     	{
       
   229                     	// Location request is needed based on evaluating
       
   230             			// modified triggers
       
   231                     	RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
   232                     	return;
       
   233                     	}
       
   234                     // Switch to estimation of update interval
       
   235                     iState = EUpdateIntervalEstimation;
       
   236                     SetEvent();
       
   237                     }
       
   238                 else
       
   239                     {
       
   240                     Term();
       
   241                     }
       
   242                 }
       
   243             break;
       
   244 
       
   245         case ESleep:
       
   246             iProjectedState = EIdle;
       
   247             iState = ESleep;
       
   248             SetEvent();
       
   249             break;
       
   250             
       
   251         case EIdle:
       
   252             if( EIdle == iState && EIdle == iProjectedState
       
   253                            && iView->CoordTriggerCount() )
       
   254                 {
       
   255                 RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
   256                 }
       
   257             break;
       
   258             
       
   259         default:
       
   260             break;
       
   261             }
       
   262      }
       
   263 
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // CLbtCoOrdinateSupervisor::Suspend
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 void CLbtCoOrdinateSupervisor::Suspend()
       
   270     {
       
   271     FUNC_ENTER("CLbtCoOrdinateSupervisor::Suspend");
       
   272     iCellChangeHandler->Remove( this );
       
   273     switch( iState )
       
   274         {
       
   275     case ELocationAcquisition:
       
   276     	if( iLastLocationFixType == EProperFix )
       
   277     		{
       
   278     		iLocationRequestor->Cancel();
       
   279     		}
       
   280     	else
       
   281     		{
       
   282     		iLocationRequestor->CancelFixFromNpp();
       
   283     		}
       
   284     	
       
   285         iProjectedState = iState;
       
   286         iState = EIdle;
       
   287         break;
       
   288         
       
   289     case ETriggerEvaluation:
       
   290         iProjectedState = ETriggerEvaluation;
       
   291         iState = EIdle;
       
   292         break;
       
   293         
       
   294     case EUpdateIntervalEstimation:
       
   295         iProjectedState = EUpdateIntervalEstimation;
       
   296         iState = EIdle;
       
   297         break;
       
   298         
       
   299     case ESleep:
       
   300         iTimer->Cancel();
       
   301         iProjectedState = iState;
       
   302         iState = EIdle;
       
   303                 
       
   304     case EIdle:
       
   305         break;
       
   306         
       
   307     default:
       
   308         break;
       
   309         }
       
   310     
       
   311     Cancel();
       
   312     }
       
   313     
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CLbtCoOrdinateSupervisor::Reset
       
   317 // -----------------------------------------------------------------------------
       
   318 //
       
   319 void CLbtCoOrdinateSupervisor::Reset()
       
   320     {
       
   321     iState = iProjectedState = EIdle;
       
   322     iNearestTriggers.Reset();
       
   323     iLocReqCount = 0;
       
   324     TPositionInfo posInfo;
       
   325     iPosInfo = posInfo;
       
   326     iFixForFiringCloseTriggers = EFalse;
       
   327     }
       
   328 
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // CLbtCoOrdinateSupervisor::GetPositionInfo
       
   332 // Processes the location information obtained from location requestor
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 void CLbtCoOrdinateSupervisor::GetPositionInfoL()
       
   336     {
       
   337     FUNC_ENTER("CLbtCoOrdinateSupervisor::GetPositionInfo");
       
   338     
       
   339     // Update location acquisition status information
       
   340     
       
   341     if( !( (KErrNone == iStatus.Int()) ||
       
   342     	   (KPositionQualityLoss == iStatus.Int()) ) )
       
   343     	{
       
   344     	ERROR("Position Information with : %d",iStatus.Int());
       
   345     	iStatusManager->ReportLocationAcquisitionStatus( iStatus.Int() );
       
   346     	    	
       
   347     	// The following check determines if there was a problem using the 
       
   348     	// specified positioning technology to retrieve position information
       
   349     	if( KErrNotFound == iStatus.Int() &&
       
   350     	    iLastLocationFixType == EProperFix )
       
   351     	    {
       
   352     	    LOG("Specified PSY not found");
       
   353     	    iAcquisitionStatus = ELocationAcquisitionNoMethod;
       
   354     	    
       
   355     	    if( iPsyChangeListner == NULL )
       
   356     	        {
       
   357     	        iPsyChangeListner = CLbtPsyChangeListner::NewL( *this );
       
   358     	        }
       
   359     	    iPsyChangeListner->StartToListen( iModuleId );
       
   360     	    LOG1("Listen to PSY change:%x",iModuleId);
       
   361     	    TUid defaultID = { 0XFFFFFFFF };
       
   362     	    if( iLocationRequestor->GetPositionModuleId() != defaultID )
       
   363     	        {
       
   364     	        LOG("Use default proxy");
       
   365     	        // switch to using default positioning technology
       
   366     	        iModuleId = defaultID;
       
   367     	        RequestTerminalPosition( iSettings.iLocationRequestTimeout,EProperFix );   
       
   368     	        }
       
   369     	    }
       
   370     	else
       
   371     	    {
       
   372     	    LOG("Location acquisition failed");
       
   373     	    if( iFixForFiringCloseTriggers && 
       
   374     	        (KErrTimedOut == iStatus.Int())&&
       
   375     	        iLastLocationFixType == EProperFix )
       
   376     	        {
       
   377     	        LOG("Firing Close triggers");
       
   378                 FireClosestTriggers();                
       
   379                 RequestTerminalPosition(iSettings.iLocationRequestTimeout, EProperFix);
       
   380                 }
       
   381             else
       
   382                 {
       
   383                 if( iLastLocationFixType == EProperFix )
       
   384                     {
       
   385                     // Get fix from NPP PSY
       
   386                     LOG("Timed Out. Taking fix from NPP");
       
   387                     RequestTerminalPosition( iSettings.iLocationRequestTimeout, EFixFromNpp );
       
   388                     return;
       
   389                     
       
   390                     /*
       
   391                     iState = ESleep;
       
   392                     iTimer->Set( iStatus, KSleepTimeOnLocAcqFailure, ETrue );               
       
   393                     SetActive();
       
   394 
       
   395                     if( KErrAccessDenied == iStatus.Int() )
       
   396                         {
       
   397                         iAcquisitionStatus = ELocationAcquisitionPrivacyReject;
       
   398                         }
       
   399                     else 
       
   400                         {
       
   401                         iAcquisitionStatus = ELocationAcquisitionFailure;
       
   402                         }*/
       
   403                     }
       
   404                 else
       
   405                     {
       
   406                     LOG("Npp psy failed to provide fix. Sleep now");
       
   407                     iState = ESleep;
       
   408                     iTimer->Set( iStatus, KSleepTimeOnLocAcqFailure, ETrue );               
       
   409                     SetActive();
       
   410 
       
   411                     if( KErrAccessDenied == iStatus.Int() )
       
   412                         {
       
   413                         iAcquisitionStatus = ELocationAcquisitionPrivacyReject;
       
   414                         }
       
   415                     else 
       
   416                         {
       
   417                         iAcquisitionStatus = ELocationAcquisitionFailure;
       
   418                         }
       
   419                     }
       
   420                 }
       
   421     	    }
       
   422 
       
   423     	if( iFixForFiringCloseTriggers )
       
   424     	    {
       
   425     	    iFixForFiringCloseTriggers = EFalse;
       
   426     	    }
       
   427 
       
   428     	// Update supervision dynamic info to the strategy class
       
   429         TLbtStrategySupervisionDynamicInfo supervisionDynamicInfo;
       
   430         supervisionDynamicInfo.iDistanceToNearestTrigger = 0.0;
       
   431         supervisionDynamicInfo.iLatestAcquiredPosInfo = iPosInfo;
       
   432         supervisionDynamicInfo.iLocationAcquisitionStatus = iAcquisitionStatus;
       
   433         supervisionDynamicInfo.iNearestTriggerId = 0;
       
   434     
       
   435         iEngObserver->ReportTriggeringSupervisionStatus( supervisionDynamicInfo );    
       
   436     	return;
       
   437     	}
       
   438 
       
   439 	if( iStatus.Int() == KPositionQualityLoss )
       
   440 		{
       
   441 		TPosition currentPosition;
       
   442 		iPosInfo.GetPosition( currentPosition );
       
   443 		LOG("Received KPositionQualityLoss");
       
   444 		LOG1("Lat:%f",currentPosition.Latitude());
       
   445 		LOG1("Long:%f",currentPosition.Longitude());
       
   446 		LOG1("HA:%f",currentPosition.HorizontalAccuracy());
       
   447 		}
       
   448     		
       
   449     iStatusManager->ReportLocationAcquisitionStatus( KErrNone );
       
   450     // The fix was taken to fire nearest triggers then reset the flag
       
   451     // to EFalse since the fix was successful and the nearest triggers will be
       
   452     // evaluated and will be fired
       
   453     if(iFixForFiringCloseTriggers)
       
   454         {
       
   455         iFixForFiringCloseTriggers = EFalse;
       
   456         }
       
   457     
       
   458     TPosition currentPosition, prevPosition;
       
   459     iPosInfo.GetPosition( currentPosition );
       
   460     iPrevPosInfo.GetPosition( prevPosition );
       
   461     
       
   462     if( Math::IsNaN( currentPosition.Latitude() ) || 
       
   463         Math::IsNaN( currentPosition.Longitude() ) )
       
   464     	{
       
   465     	LOG("ERROR:Lat/Long is Nan. Sleep now");
       
   466     	iState = ESleep;
       
   467         iTimer->Set( iStatus, KSleepTimeOnLocAcqFailure, ETrue );               
       
   468         SetActive();
       
   469 
       
   470         if( KErrAccessDenied == iStatus.Int() )
       
   471             {
       
   472             iAcquisitionStatus = ELocationAcquisitionPrivacyReject;
       
   473             }
       
   474         else 
       
   475             {
       
   476             iAcquisitionStatus = ELocationAcquisitionFailure;
       
   477             }
       
   478     	return;
       
   479     	}
       
   480     
       
   481     // Record the time at which we got the fix
       
   482     iLastFixTime.UniversalTime();
       
   483     
       
   484     // Take note of reference time that would be used during estimation of 
       
   485     // sleep interval
       
   486     iAcquisitionStatus = ELocationAcquisitionActive;
       
   487     
       
   488     iLocReqCount++;
       
   489     iLocationRequestor->GetModuleInfo( iPosInfo.ModuleId() );    
       
   490         
       
   491     if( iLocArea.iCellId && iLastCellRequestStatus == KErrNone )
       
   492         {
       
   493         LOG("Writing position to DB");
       
   494         LOG1("Cell Id = %d", iLocArea.iCellId );
       
   495         LOG1("LAC = %d", iLocArea.iLocationAreaCode );
       
   496         // Add current cell id position to cell-id database
       
   497         TInt countryCode,networkCode;
       
   498         
       
   499         TLex lex( iNwInfo.iCountryCode );
       
   500         lex.Val( countryCode );
       
   501         
       
   502         lex.Assign( iNwInfo.iNetworkId );
       
   503         lex.Val( networkCode );
       
   504         
       
   505         TPosition cellPosition;
       
   506         iPosInfo.GetPosition( cellPosition );
       
   507         if( iLastLocationFixType == EProperFix )
       
   508             {
       
   509             cellPosition.SetHorizontalAccuracy( 3000 );
       
   510             }
       
   511         
       
   512         iCellIdDatabase->InsertCidLocation( countryCode,
       
   513                                             networkCode,
       
   514                                             iLocArea.iLocationAreaCode,
       
   515                                             iLocArea.iCellId,
       
   516                                             cellPosition );
       
   517         }
       
   518     
       
   519     // Check if there is no movement from last location fix. If true then 
       
   520     // re-evaluate sleep interval
       
   521     TReal32 dist;
       
   522     currentPosition.Distance( prevPosition, dist );
       
   523     if( dist == 0 )
       
   524         {
       
   525         iState = EUpdateIntervalEstimation;
       
   526         SetEvent();
       
   527         }
       
   528     
       
   529     LOG1("Lat:%f",currentPosition.Latitude());
       
   530 	LOG1("Long:%f",currentPosition.Longitude());
       
   531 	LOG1("HA:%f",currentPosition.HorizontalAccuracy());
       
   532     
       
   533     // Switch to idle state as refresh is an async operation. Set projected 
       
   534     // state to trigger evaluation which will commence once the refresh 
       
   535     // operation is complete
       
   536     iState = ETriggerEvaluation;
       
   537     SetEvent();
       
   538 
       
   539     }
       
   540 
       
   541 
       
   542 // -----------------------------------------------------------------------------
       
   543 // CLbtCoOrdinateSupervisor::EvaluateTriggersL
       
   544 // Evaluates triggers based on the location information obtained 
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 void CLbtCoOrdinateSupervisor::EvaluateTriggersL()
       
   548     {
       
   549     FUNC_ENTER("CLbtCoOrdinateSupervisor::EvaluateTriggersL");
       
   550     
       
   551     // Reset nearest trigger array
       
   552     iNearestTriggers.Reset();
       
   553     
       
   554     // TODO: In case of updates to trigger information do not change state
       
   555     //       else change state to EUpdateIntervalEstimation
       
   556     CLbtContainerTriggerEntry* conTrigger;
       
   557     
       
   558     // ResetViewIterator will switch state to Idle if there are no triggers in 
       
   559     // the system
       
   560     if( KErrNone != ResetViewIterator() )
       
   561         {
       
   562         return;
       
   563         }
       
   564 
       
   565     while( iViewIterator.NextL( conTrigger ) )
       
   566         {
       
   567         if( conTrigger )    
       
   568             {
       
   569             CLbtTriggerEntry* trigger = conTrigger->TriggerEntry();
       
   570             if( CLbtTriggerConditionBase::ETriggerConditionArea == 
       
   571                                                 trigger->GetCondition()->Type() )
       
   572                 {
       
   573                 // Area type trigger
       
   574                 CLbtTriggerConditionArea* triggerConArea = 
       
   575                                         static_cast< CLbtTriggerConditionArea* >
       
   576                                                 ( trigger->GetCondition() );
       
   577                    
       
   578                 switch( triggerConArea->TriggerArea()->Type() )
       
   579                     {
       
   580                 	// Circular area
       
   581                 	case CLbtGeoAreaBase::ECircle:
       
   582                 		{
       
   583                 		if( iLastLocationFixType == EProperFix )
       
   584                             {
       
   585                             EvalCircularTriggerL( conTrigger );
       
   586                             }
       
   587                         else if( iLastLocationFixType == EFixFromDb || iLastLocationFixType == EFixFromNpp )
       
   588                             {
       
   589                             if( EvalCircularTriggerBasedOnCellPositionL( conTrigger ) )
       
   590                                 {
       
   591                                 if( iLastLocationFixType == EFixFromNpp )
       
   592                                 	{
       
   593                                 	// Fix is taken from NPP only when Proper Fix fails. Now we should
       
   594                                 	// sleep for location acquisition failure time our period since there is no point
       
   595                                 	// in attempting another proper fix
       
   596                                 	iState = ESleep;
       
   597 				                    iTimer->Set( iStatus, KSleepTimeOnLocAcqFailure, ETrue );               
       
   598 				                    SetActive();
       
   599 
       
   600 				                    if( KErrAccessDenied == iStatus.Int() )
       
   601 				                        {
       
   602 				                        iAcquisitionStatus = ELocationAcquisitionPrivacyReject;
       
   603 				                        }
       
   604 				                    else 
       
   605 				                        {
       
   606 				                        iAcquisitionStatus = ELocationAcquisitionFailure;
       
   607 				                        }
       
   608                                 	}
       
   609                                 else
       
   610                                 	{
       
   611                                 	RequestTerminalPosition( iSettings.iLocationRequestTimeout,EProperFix );
       
   612                                 	}                                
       
   613                                 return;
       
   614                                 }
       
   615                             }                            
       
   616                     	break;
       
   617                 		}                    
       
   618                 	default:
       
   619                     	break;
       
   620                     }
       
   621                 }
       
   622             }
       
   623         }
       
   624         
       
   625     // Update supervision dynamic info to the strategy class
       
   626     TLbtStrategySupervisionDynamicInfo supervisionDynamicInfo;
       
   627     if( iNearestTriggers.Count() )
       
   628         {
       
   629         supervisionDynamicInfo.iDistanceToNearestTrigger = iNearestTriggers[0].distance;
       
   630         supervisionDynamicInfo.iNearestTriggerId = iNearestTriggers[0].id;
       
   631         }
       
   632     supervisionDynamicInfo.iLatestAcquiredPosInfo = iPosInfo;
       
   633     supervisionDynamicInfo.iLocationAcquisitionStatus = iAcquisitionStatus;
       
   634     
       
   635     
       
   636     iEngObserver->ReportTriggeringSupervisionStatus( supervisionDynamicInfo );
       
   637     
       
   638     iState = EUpdateIntervalEstimation;
       
   639     SetEvent();
       
   640     }
       
   641     
       
   642 
       
   643 // -----------------------------------------------------------------------------
       
   644 // CLbtCoOrdinateSupervisor::EvaluateTriggers
       
   645 // Evaluates triggers based on the location information obtained 
       
   646 // -----------------------------------------------------------------------------
       
   647 //
       
   648 TBool CLbtCoOrdinateSupervisor::EvaluateModifiedTriggersL()
       
   649     {
       
   650     FUNC_ENTER("CLbtCoOrdinateSupervisor::EvaluateModifiedTriggersL");
       
   651     
       
   652     // Retrieve modified trigger list from trigger view to be supervised
       
   653     RArray< TLbtTriggerId > modifiedTriggers;
       
   654     iView->GetModifiedTriggers( modifiedTriggers );
       
   655     CleanupClosePushL( modifiedTriggers );
       
   656     if( modifiedTriggers.Count() )
       
   657         {
       
   658         // TODO: Need to check for the deletion of
       
   659         // Create an iterator to parse through the modified trigger list
       
   660         CLbtTriggerView::TTriggerViewIter iter = iView->Begin( &modifiedTriggers, CLbtGeoAreaBase::ECircle );        
       
   661         
       
   662         CLbtContainerTriggerEntry* conTrigger;
       
   663         while( iter.NextL( conTrigger ) )
       
   664             {
       
   665             if( conTrigger )
       
   666                 {
       
   667                 CLbtTriggerEntry* trigger = conTrigger->TriggerEntry();
       
   668                 if( CLbtTriggerConditionBase::ETriggerConditionArea == 
       
   669                                                     trigger->GetCondition()->Type() )
       
   670                     {
       
   671                     // Area type trigger
       
   672                     CLbtTriggerConditionArea* triggerConArea = 
       
   673                                             static_cast< CLbtTriggerConditionArea* >
       
   674                                                     ( trigger->GetCondition() );
       
   675                        
       
   676                     switch( triggerConArea->TriggerArea()->Type() )
       
   677                         {
       
   678 	                    // Circular area
       
   679 	                    case CLbtGeoAreaBase::ECircle:
       
   680 	                        if( iLastLocationFixType == EProperFix )
       
   681 	                            {
       
   682 	                            EvalCircularTriggerL( conTrigger );
       
   683 	                            }
       
   684 	                        else if( iLastLocationFixType == EFixFromDb || iLastLocationFixType == EFixFromNpp )
       
   685 	                            {
       
   686 	                            if( EvalCircularTriggerBasedOnCellPositionL( conTrigger ) )
       
   687 	                                {
       
   688 	                                CleanupStack::PopAndDestroy();  // modifiedTriggers
       
   689 	                                return ETrue;
       
   690 	                                }
       
   691 	                            }
       
   692 	                        break; 
       
   693 	                        
       
   694 	                    default:
       
   695 	                        break;
       
   696                         }
       
   697                     }
       
   698                 }
       
   699             }        
       
   700         }
       
   701         
       
   702     CleanupStack::PopAndDestroy();  // modifiedTriggers
       
   703     return EFalse;
       
   704     }
       
   705     
       
   706 
       
   707 // -----------------------------------------------------------------------------
       
   708 // CLbtCoOrdinateSupervisor::EvalCircularTrigger
       
   709 // Evaluates triggers with circular area definition
       
   710 // -----------------------------------------------------------------------------
       
   711 //
       
   712 void CLbtCoOrdinateSupervisor::EvalCircularTriggerL( 
       
   713                                           CLbtContainerTriggerEntry* aTrigger )
       
   714     {
       
   715     FUNC_ENTER("CLbtCoOrdinateSupervisor::EvalCircularTrigger");
       
   716     
       
   717     
       
   718     // Extract strategy data
       
   719     TStrategyData strategyData = aTrigger->StrategyData();                                          
       
   720     
       
   721     TInt remRearmTime = 0;
       
   722     TReal distanceToLatestLocation = 0.0;
       
   723     TBool hasRearmTimeExpired = ETrue;
       
   724     
       
   725     LOGSTRING("Trigger: \"%S\" ", &(aTrigger->TriggerEntry()->Name()));
       
   726         
       
   727     if( strategyData.iFireTime )
       
   728         {
       
   729         TTime triggerFiredTime( strategyData.iFireTime );
       
   730 
       
   731         TTime currentTime;
       
   732         currentTime.UniversalTime();
       
   733         
       
   734         TTimeIntervalSeconds interval;
       
   735         currentTime.SecondsFrom( triggerFiredTime, interval );
       
   736         
       
   737         remRearmTime = aTrigger->TriggerEntry()->TimeToRearm() - interval.Int();
       
   738         
       
   739         
       
   740         if( remRearmTime <= 0 )
       
   741             {
       
   742             remRearmTime = 0;
       
   743             strategyData.iFireTime = 0;
       
   744             }
       
   745         else
       
   746         	{
       
   747         	LOG("Rearm Time has not expired");
       
   748         	hasRearmTimeExpired = EFalse;
       
   749         	}
       
   750         }
       
   751         
       
   752     CLbtTriggerConditionArea* trgCondition = 
       
   753                               static_cast< CLbtTriggerConditionArea* >
       
   754                               ( ( aTrigger->TriggerEntry() )->GetCondition() );
       
   755     
       
   756     CLbtGeoCircle* circularArea = static_cast< CLbtGeoCircle* >
       
   757                                                ( trgCondition->TriggerArea() );
       
   758 
       
   759     // Calculate distance of trigger from current location
       
   760     TReal32 distanceToCenter;
       
   761     TPosition currentPosition;
       
   762     iPosInfo.GetPosition( currentPosition );
       
   763     TInt err = currentPosition.Distance( circularArea->Center(), 
       
   764                                          distanceToCenter );
       
   765     if( KErrNone != err )
       
   766         {
       
   767         ERROR("Error in calculating distance:%d",err);
       
   768         LOG1("Current Lat:%f",currentPosition.Latitude());
       
   769 	    LOG1("Current Long:%f",currentPosition.Longitude());   
       
   770 	    LOG1("Trigger Lat:%f",circularArea->Center().Latitude());   
       
   771 	    LOG1("Trigger Long:%f",circularArea->Center().Longitude());
       
   772         return;
       
   773         }
       
   774 
       
   775     // Determine trigger radius and hysteresis radius to be used for supervision
       
   776     // based on the accuracy of location fix
       
   777     TTriggerArea triggerArea;
       
   778     TReal positionAccuracy = currentPosition.HorizontalAccuracy();    
       
   779     triggerArea = EstimateTriggerRadii( circularArea->Radius(), 
       
   780                     aTrigger->ExtendedTriggerInfo()->HysteresisRadius(), 
       
   781                         positionAccuracy );
       
   782     
       
   783     // ENTRY Trigger
       
   784     // Determine current position of terminal relative to the trigger area and 
       
   785     // set trigger fire status accordingly
       
   786     if( CLbtTriggerConditionArea::EFireOnEnter == trgCondition->Direction() )
       
   787         {
       
   788         TLbtTriggerDataMask dataMask = 0;
       
   789         
       
   790         TReal tolerableRadius = CalculateTolerableRadius( triggerArea.triggerRadius );
       
   791         // Terminal is inside trigger area
       
   792         if( ( distanceToCenter < tolerableRadius ) && 
       
   793             ( ( distanceToCenter + positionAccuracy ) <= triggerArea.hysteresisRadius ) )
       
   794             {
       
   795             LOG("Inside triggerin area");
       
   796             // If trigger in active state then fire trigger and set state to
       
   797             // inactive. If trigger is inactive nothing is to be done other
       
   798             // than calculating its distance from the hysteresis boundary
       
   799             if( EActive == strategyData.iActivityStatus )
       
   800                 {
       
   801 				LOG("Active trigger");
       
   802                 // Check FireOnCreation flag here. If EFalse then dont 
       
   803                 // fire the trigger. Instead only change the activity
       
   804                 // status.
       
   805                 if( aTrigger->ExtendedTriggerInfo()->IsTriggerFireOnCreation() &&
       
   806                     hasRearmTimeExpired )
       
   807                     {
       
   808                     // Set trigger state to fired
       
   809                     aTrigger->ExtendedTriggerInfo()->SetTriggerFiredState( ETrue );
       
   810                     TLbtTriggerFireInfo triggerFireInfo;
       
   811                     TPositionInfo positionInfo;
       
   812                     triggerFireInfo.iTriggerId = aTrigger->TriggerEntry()->Id();
       
   813                     triggerFireInfo.iFiredPositionInfo = iPosInfo;
       
   814                     
       
   815                     aTrigger->ExtendedTriggerInfo()->SetFiredInfo( triggerFireInfo );
       
   816                     
       
   817                     // Time at which trigger fired
       
   818                     TTime triggerFiredTime;
       
   819                     triggerFiredTime.UniversalTime();
       
   820                     LOG("TRIGGER FIRED");
       
   821                     
       
   822                     strategyData.iFireTime = triggerFiredTime.Int64();
       
   823                     
       
   824                     remRearmTime = aTrigger->TriggerEntry()->TimeToRearm();
       
   825                     dataMask |= 
       
   826                     CLbtContainerTriggerEntry::EContainerAttributeIsFired | 
       
   827                     CLbtContainerTriggerEntry::EContainerAttributeFireInfo ;
       
   828                     }
       
   829                 
       
   830                 // Set trigger to inactive state                
       
   831                 strategyData.iActivityStatus = EInactive;
       
   832                 }
       
   833             
       
   834             // Calculate distance to current location and update trigger's 
       
   835             // dynamic info. This distance is (rH - D) where D is the distance 
       
   836             // between the two centers and rH is the radius of the hysteresis 
       
   837             // circle. Here the radius of hysteresis boundary is considered for 
       
   838             // distance calculation as this trigger would undergo a state 
       
   839             // change only when it crosses the hysteresis area
       
   840             distanceToLatestLocation = Abs( triggerArea.hysteresisRadius - distanceToCenter );
       
   841             }
       
   842             
       
   843         // Terminal is outside hysteresis area
       
   844         else if( distanceToCenter > ( triggerArea.hysteresisRadius + positionAccuracy ) )
       
   845             {
       
   846             if( EInactive == strategyData.iActivityStatus )
       
   847                 {
       
   848                 // Reset trigger state to valid
       
   849                 strategyData.iActivityStatus = EActive;     
       
   850                 LOG("Trigger activated");
       
   851                 }
       
   852                 
       
   853             // Calculate distance of trigger to current location and update
       
   854             // trigger's dynamic info. This distance is (D - rT) where D is 
       
   855             // the distance between two centers and rT is the radius of trigger. 
       
   856             // State change will occur only when the terminal moves beyond the
       
   857             // boundary of the trigger
       
   858             distanceToLatestLocation = Abs( distanceToCenter - triggerArea.triggerRadius );
       
   859             }
       
   860 
       
   861         // Terminal is inside hysteresis area. 
       
   862         else
       
   863             {
       
   864             // Trigger does not undergo any state change in this region. Theres 
       
   865             // only distance to be determined here
       
   866             if( EActive == strategyData.iActivityStatus )
       
   867                 {
       
   868                 // Terminal was outside hysteresis area earlier. Distance is
       
   869                 // therefore (D - rT)
       
   870                 distanceToLatestLocation = Abs( distanceToCenter - triggerArea.triggerRadius );
       
   871                 }
       
   872             else
       
   873                 {
       
   874                 // Terminal was inside trigger area earlier. Distance is
       
   875                 // therefore (rH - D)
       
   876                 distanceToLatestLocation = Abs( triggerArea.hysteresisRadius - distanceToCenter );
       
   877                 }
       
   878             }
       
   879         
       
   880         // Set FireOnCreation flag to ETrue here if its not already
       
   881         // ETrue. This is done to ensure that the trigger is fired 
       
   882         // in the subsequent iterations if the triggering conditions
       
   883         // are satisfied.
       
   884         if( !aTrigger->ExtendedTriggerInfo()->IsTriggerFireOnCreation() )
       
   885             {
       
   886             aTrigger->ExtendedTriggerInfo()->SetTriggerFireOnCreation( ETrue );
       
   887             dataMask |= CLbtContainerTriggerEntry::EContainerAttributeIsTriggerFireOnCreation;
       
   888             }
       
   889         
       
   890         if( dataMask )
       
   891             {
       
   892             iView->UpdateTriggerInfo( CLbtGeoAreaBase::ECircle,iPosInfo, aTrigger, dataMask );            
       
   893             }
       
   894         }
       
   895         
       
   896     // EXIT Trigger
       
   897     else
       
   898         {
       
   899         TLbtTriggerDataMask dataMask = 0;
       
   900         // Retrieve boundary information of trigger
       
   901         TTriggerBoundary boundary = EUndefined;
       
   902         
       
   903         // Retrieve boundary information of trigger
       
   904         ( strategyData.iBoundaryCondition >= 0 && strategyData.iBoundaryCondition <= 2 )?boundary =
       
   905                                      TTriggerBoundary( strategyData.iBoundaryCondition ):boundary;
       
   906         
       
   907         TReal tolerableRadius = CalculateTolerableRadius( triggerArea.triggerRadius );                             
       
   908         
       
   909         // Terminal is inside trigger area
       
   910         if( ( distanceToCenter < tolerableRadius ) && 
       
   911             ( ( distanceToCenter + positionAccuracy ) <= triggerArea.hysteresisRadius ) )
       
   912             {
       
   913             // Check boundary condition to determine if the terminal has moved
       
   914             // inside the trigger area without having gone beyond the area of
       
   915             // hysteresis. In this case the trigger shall not be set as active
       
   916             if( EOutside != boundary && 
       
   917                     EInactive == strategyData.iActivityStatus )
       
   918                 {
       
   919                 // Set trigger state to active
       
   920                 strategyData.iActivityStatus = EActive;
       
   921                 }
       
   922             
       
   923             // Set boundary as Outside
       
   924             strategyData.iBoundaryCondition =  TInt( EOutside );
       
   925             
       
   926             if( EActive == strategyData.iActivityStatus )
       
   927                 {
       
   928                 // Set Distance to the border of trigger area. This distance is
       
   929                 // (rT - D).
       
   930                 distanceToLatestLocation = Abs( triggerArea.triggerRadius - distanceToCenter );
       
   931                 }
       
   932             else
       
   933                 {
       
   934                 // Set distance to border of hysteresis area. This distance is
       
   935                 // (rH - D) where rH is the radius of hysteresis and D is the 
       
   936                 // distance between the center of trigger and the center of 
       
   937                 // location
       
   938                 distanceToLatestLocation = Abs( triggerArea.hysteresisRadius - distanceToCenter );
       
   939                 }
       
   940             }
       
   941             
       
   942         // Terminal is outside hysteresis area  
       
   943         else if( ( distanceToCenter > triggerArea.hysteresisRadius )  &&
       
   944             ( distanceToCenter > ( triggerArea.triggerRadius + positionAccuracy ) ) )
       
   945             {
       
   946             if( EActive == strategyData.iActivityStatus  )
       
   947                 {
       
   948                 // Check FireOnCreation flag here. If EFalse then dont 
       
   949                 // fire the trigger. Instead only change the activity
       
   950                 // status.
       
   951                 if( aTrigger->ExtendedTriggerInfo()->IsTriggerFireOnCreation() &&
       
   952                     hasRearmTimeExpired )
       
   953                     {
       
   954                     // Set trigger state to fired
       
   955                     aTrigger->ExtendedTriggerInfo()->SetTriggerFiredState( ETrue );
       
   956                     
       
   957                     TLbtTriggerFireInfo triggerFireInfo;
       
   958                     TPositionInfo positionInfo;
       
   959                     triggerFireInfo.iTriggerId = aTrigger->TriggerEntry()->Id();
       
   960                     triggerFireInfo.iFiredPositionInfo = iPosInfo;
       
   961                     
       
   962                     aTrigger->ExtendedTriggerInfo()->SetFiredInfo( triggerFireInfo );
       
   963                     
       
   964                      // Time at which trigger fired
       
   965                     TTime triggerFiredTime;
       
   966                     triggerFiredTime.UniversalTime();
       
   967                     strategyData.iFireTime = triggerFiredTime.Int64();
       
   968                     LOG("TRIGGER FIRED");
       
   969                     remRearmTime = aTrigger->TriggerEntry()->TimeToRearm();             
       
   970                     dataMask |= 
       
   971                     CLbtContainerTriggerEntry::EContainerAttributeIsFired | 
       
   972                     CLbtContainerTriggerEntry::EContainerAttributeFireInfo;
       
   973                     }
       
   974                 
       
   975                 // Set the trigger state to inactive
       
   976                 strategyData.iActivityStatus = EInactive;
       
   977                 
       
   978                 }
       
   979 
       
   980             // Set boundary as Inside
       
   981             strategyData.iBoundaryCondition = TInt( EInside );
       
   982             
       
   983             // Calculate distance to border of trigger area. This distance
       
   984             // is (D - rT)
       
   985             distanceToLatestLocation = Abs( distanceToCenter - triggerArea.triggerRadius );
       
   986             }
       
   987         
       
   988         // Terminal is inside hysteresis area
       
   989         else
       
   990             {
       
   991             if( EOutside == boundary && EActive == strategyData.iActivityStatus )
       
   992                 {
       
   993                 // Check FireOnCreation flag here. If EFalse then dont 
       
   994                 // fire the trigger. Instead only change the activity
       
   995                 // status.
       
   996                 if( aTrigger->ExtendedTriggerInfo()->IsTriggerFireOnCreation() )
       
   997                     {
       
   998                     // Set trigger state to fired
       
   999                     aTrigger->ExtendedTriggerInfo()->SetTriggerFiredState( ETrue );
       
  1000                     TLbtTriggerFireInfo triggerFireInfo;
       
  1001                     TPositionInfo positionInfo;
       
  1002                     triggerFireInfo.iTriggerId = aTrigger->TriggerEntry()->Id();
       
  1003                     triggerFireInfo.iFiredPositionInfo = iPosInfo;
       
  1004                     
       
  1005                     aTrigger->ExtendedTriggerInfo()->SetFiredInfo( triggerFireInfo );
       
  1006                     
       
  1007                      // Time at which trigger fired
       
  1008                     TTime triggerFiredTime;
       
  1009                     triggerFiredTime.UniversalTime();
       
  1010                     
       
  1011                     strategyData.iFireTime = triggerFiredTime.Int64();
       
  1012                     strategyData.iBoundaryCondition =  TInt( EOutside );
       
  1013                     
       
  1014                     remRearmTime = aTrigger->TriggerEntry()->TimeToRearm();             
       
  1015                     dataMask |= 
       
  1016                     CLbtContainerTriggerEntry::EContainerAttributeIsFired | 
       
  1017                     CLbtContainerTriggerEntry::EContainerAttributeFireInfo;
       
  1018                     }
       
  1019                 
       
  1020                 // Set the trigger state to inactive
       
  1021                 strategyData.iActivityStatus = EInactive;
       
  1022                 }
       
  1023 
       
  1024             if( EOutside != boundary )
       
  1025                 {
       
  1026                 // Set the trigger state to inactive. This is done here because
       
  1027                 // if a trigger was newly created (state is active) and it is
       
  1028                 // found to be within hysteresis area, then the activity status 
       
  1029                 // needs to be set to inactive to enable the trigger to be
       
  1030                 // handled appropriately when terminal moves inside trigger
       
  1031                 // area.
       
  1032                 strategyData.iActivityStatus = EInactive;
       
  1033                 // Calclulate distance to border of trigger area. This 
       
  1034                 // distance is (D - rT)
       
  1035                 distanceToLatestLocation = Abs( distanceToCenter - triggerArea.triggerRadius );
       
  1036                 }
       
  1037             else 
       
  1038                 {
       
  1039                 // Calculate distance to the boundary of hysteresis. This 
       
  1040                 // distance is (rH - D)
       
  1041                 distanceToLatestLocation = 
       
  1042                                Abs( triggerArea.hysteresisRadius - distanceToCenter );
       
  1043                 }
       
  1044             }
       
  1045         
       
  1046         // Set FireOnCreation flag to ETrue here if its not already
       
  1047         // ETrue. This is done to ensure that the trigger is fired 
       
  1048         // in the subsequent iterations if the triggering conditions
       
  1049         // are satisfied.
       
  1050         if( !aTrigger->ExtendedTriggerInfo()->IsTriggerFireOnCreation() )
       
  1051             {
       
  1052             aTrigger->ExtendedTriggerInfo()->SetTriggerFireOnCreation( ETrue );
       
  1053             dataMask |= CLbtContainerTriggerEntry::EContainerAttributeIsTriggerFireOnCreation;
       
  1054             }
       
  1055         
       
  1056         if( dataMask )    
       
  1057             {
       
  1058             iView->UpdateTriggerInfo( CLbtGeoAreaBase::ECircle,iPosInfo, aTrigger, dataMask );
       
  1059             }
       
  1060         }
       
  1061     aTrigger->SetStrategyData( strategyData );    
       
  1062     UpdateNearestTriggers( aTrigger->TriggerEntry()->Id(), distanceToLatestLocation , remRearmTime );
       
  1063     LOG1("DistToTrig:%f",distanceToLatestLocation );
       
  1064     }
       
  1065 
       
  1066 
       
  1067 // -----------------------------------------------------------------------------
       
  1068 // CLbtCoOrdinateSupervisor::EvalCircularTriggerBasedOnCellPosition
       
  1069 // Evaluates triggers with circular area definition
       
  1070 // -----------------------------------------------------------------------------
       
  1071 //
       
  1072 TBool CLbtCoOrdinateSupervisor::EvalCircularTriggerBasedOnCellPositionL( 
       
  1073                                           CLbtContainerTriggerEntry* aTrigger )
       
  1074     {
       
  1075     TTime currentTime;
       
  1076     currentTime.UniversalTime();
       
  1077     
       
  1078     CLbtTriggerConditionArea* trgCondition = 
       
  1079                               static_cast< CLbtTriggerConditionArea* >
       
  1080                               ( ( aTrigger->TriggerEntry() )->GetCondition() );
       
  1081         
       
  1082     // Extract strategy data
       
  1083     TStrategyData strategyData = aTrigger->StrategyData();
       
  1084     
       
  1085     TInt remRearmTime = 0;
       
  1086     TReal distanceToLatestLocation = 0.0;
       
  1087        
       
  1088     if( strategyData.iFireTime )
       
  1089         {
       
  1090         TTime triggerFiredTime( strategyData.iFireTime );
       
  1091 
       
  1092         TTimeIntervalSeconds interval;
       
  1093         currentTime.SecondsFrom( triggerFiredTime, interval );
       
  1094     
       
  1095         remRearmTime = aTrigger->TriggerEntry()->TimeToRearm() - interval.Int();
       
  1096         
       
  1097         if( remRearmTime <= 0 )            
       
  1098             {
       
  1099             remRearmTime = 0;
       
  1100             strategyData.iFireTime = 0;
       
  1101             aTrigger->SetStrategyData( strategyData );
       
  1102             }
       
  1103         }
       
  1104             
       
  1105     
       
  1106     TPosition currentPosition;
       
  1107     iPosInfo.GetPosition( currentPosition );
       
  1108     TReal positionAccuracy = currentPosition.HorizontalAccuracy();    
       
  1109     
       
  1110     CLbtGeoCircle* circularArea = static_cast< CLbtGeoCircle* >
       
  1111                                            ( trgCondition->TriggerArea() );
       
  1112                                            
       
  1113     TReal32 distanceToCenter;
       
  1114     TInt err = currentPosition.Distance( circularArea->Center(), 
       
  1115                                                         distanceToCenter );
       
  1116     if( err!=KErrNone )
       
  1117         {
       
  1118         return ETrue;
       
  1119         }
       
  1120     
       
  1121     // If the trigger is entry type,we calculate distance to the hysterisis radius
       
  1122     if( CLbtTriggerConditionArea::EFireOnEnter == trgCondition->Direction() )
       
  1123         {
       
  1124         distanceToLatestLocation = distanceToCenter -
       
  1125                                          ( positionAccuracy+aTrigger->ExtendedTriggerInfo()->HysteresisRadius());
       
  1126                                          
       
  1127         if( distanceToLatestLocation < 0 && (remRearmTime == 0) )
       
  1128         	{
       
  1129         	// Request fix using any of the available psy
       
  1130         	LOG("Request Proper Fix");
       
  1131         	return ETrue;
       
  1132         	}
       
  1133 
       
  1134         // Activate the trigger if the trigger is outside Hysteresis area
       
  1135         if( EInactive == strategyData.iActivityStatus && distanceToLatestLocation > 0 )
       
  1136         	{
       
  1137 	   		// Activate the trigger
       
  1138     		strategyData.iActivityStatus = EActive;
       
  1139     		aTrigger->SetStrategyData( strategyData );
       
  1140     		LOG("Trigger activated based on NPP fix");
       
  1141         	}
       
  1142         UpdateNearestTriggers( aTrigger->TriggerEntry()->Id(), distanceToLatestLocation, remRearmTime );
       
  1143         }
       
  1144     // If the trigger is exit type,we calculate distance to the radius    
       
  1145     else if( CLbtTriggerConditionArea::EFireOnExit == trgCondition->Direction() )  
       
  1146         {
       
  1147         distanceToLatestLocation = distanceToCenter -
       
  1148                                      ( positionAccuracy+circularArea->Radius() );
       
  1149 
       
  1150         if( distanceToLatestLocation < 0 && (remRearmTime == 0) )
       
  1151         	{
       
  1152         	// Request fix using any of the available psy
       
  1153         	LOG("Request Proper Fix");
       
  1154         	return ETrue;
       
  1155         	}	                             
       
  1156         UpdateNearestTriggers( aTrigger->TriggerEntry()->Id(), distanceToLatestLocation,remRearmTime );                                                          
       
  1157         }
       
  1158     return EFalse;     
       
  1159     }
       
  1160 
       
  1161 // -----------------------------------------------------------------------------
       
  1162 // CLbtCoOrdinateSupervisor::EstimateSleepInterval
       
  1163 // Calculates the sleep interval
       
  1164 // -----------------------------------------------------------------------------
       
  1165 //
       
  1166 void CLbtCoOrdinateSupervisor::EstimateSleepInterval()
       
  1167     {
       
  1168     FUNC_ENTER("CLbtCoOrdinateSupervisor::EstimateSleepInterval");
       
  1169     
       
  1170     TReal maxUserSpeed = iSettings.iMaximumUserSpeed;
       
  1171         
       
  1172     TReal actualEstimatedSpeed = KMinProjSpeed;
       
  1173     // Flag to determine if the nearest trigger is an inactive trigger
       
  1174     TBool nearestTriggerInactive = EFalse;
       
  1175     
       
  1176     // This is first time when there are no previously observed values
       
  1177     if( iLocReqCount == 1 )
       
  1178         {
       
  1179         // First iteration use the minimum update interval
       
  1180         if( iNearestTriggers.Count() )
       
  1181             {
       
  1182             iSleepInterval = iNearestTriggers[0].distance / maxUserSpeed;
       
  1183             }
       
  1184         else
       
  1185             {
       
  1186             iSleepInterval = iSettings.iMinimumLocationUpdateInterval;
       
  1187             }
       
  1188         }
       
  1189     else
       
  1190         {
       
  1191         iEstimatedUserSpeed = 0.0;
       
  1192         if( (iLastLocationFixType == EFixFromDb) || 
       
  1193             (iLastLocationFixType == EFixFromNpp) )
       
  1194             {
       
  1195             iEstimatedUserSpeed = (maxUserSpeed + KMinProjSpeed)/2;
       
  1196             }
       
  1197         else if( iLastLocationFixType == EProperFix )
       
  1198             {
       
  1199             // determine average speed from previous location request which is the
       
  1200             // observed speed
       
  1201             TPosition currentPosition, prevPosition;
       
  1202             iPosInfo.GetPosition( currentPosition );
       
  1203             iPrevPosInfo.GetPosition( prevPosition );
       
  1204             
       
  1205             TReal32 avgSpeed = 0.0;
       
  1206             
       
  1207             currentPosition.Speed( prevPosition, avgSpeed );
       
  1208             TObservedValues obsValue;
       
  1209             obsValue.speed = avgSpeed;
       
  1210             obsValue.time = currentPosition.Time();
       
  1211 
       
  1212             if( iNObservedValues.Count() == maxObsValues )
       
  1213                 {
       
  1214                 iNObservedValues.Remove( 0 );
       
  1215                 }
       
  1216             iNObservedValues.Append( obsValue );
       
  1217             
       
  1218             TReal num = 0.0;
       
  1219             TReal den = 0.0;
       
  1220             TReal obsSpeed = 0.0;
       
  1221             TReal obsTime = 0.0;
       
  1222             TTime currentTime;
       
  1223 
       
  1224             // Determine average of previously obtained observed speed, time values.
       
  1225             // Use the current time value obtained from the approximation of speed.
       
  1226             currentTime.UniversalTime();
       
  1227             
       
  1228             for( TInt i = 0; i < iNObservedValues.Count(); i++ )
       
  1229                 {
       
  1230                 obsSpeed = maxUserSpeed - ( iNObservedValues[i] ).speed;
       
  1231                 TTimeIntervalSeconds timediff; 
       
  1232                 currentTime.SecondsFrom( ( iNObservedValues[i] ).time, timediff );  
       
  1233                 obsTime = timediff.Int() / constantTime;
       
  1234                 TReal timeExp = 0.0;
       
  1235                 Math::Exp( timeExp, (-1 * obsTime ) );
       
  1236                 
       
  1237                 num += obsSpeed * timeExp * timeExp;
       
  1238                 den += timeExp;
       
  1239                 }
       
  1240         
       
  1241             iEstimatedUserSpeed = maxUserSpeed - ( num / den );
       
  1242             
       
  1243             if( Math::IsNaN(iEstimatedUserSpeed) )
       
  1244             	{
       
  1245             	iEstimatedUserSpeed = maxUserSpeed;
       
  1246             	}
       
  1247 
       
  1248             actualEstimatedSpeed = iEstimatedUserSpeed;
       
  1249             LOG1("Actual estimated speed:%f",actualEstimatedSpeed);
       
  1250             
       
  1251             if(iEstimatedUserSpeed < KMinProjSpeed)
       
  1252                 {
       
  1253                 iEstimatedUserSpeed = KMinProjSpeed;
       
  1254                 }
       
  1255             // There are some cases estimate user speed goes to infinty.    
       
  1256             else if( iEstimatedUserSpeed > maxUserSpeed )    
       
  1257                 {
       
  1258                 iEstimatedUserSpeed = maxUserSpeed;
       
  1259                 }
       
  1260             }
       
  1261         
       
  1262         /**
       
  1263          * Find the position of the nearest trigger which: -
       
  1264          *
       
  1265          * a) Is Active
       
  1266          * b) Its rearm time has expired
       
  1267          */
       
  1268         TInt position = -1;
       
  1269         for( TInt i=0;i<iNearestTriggers.Count();i++ )
       
  1270             {
       
  1271             iNearestTriggers[i].minTimeRequired = iNearestTriggers[i].distance / iEstimatedUserSpeed;
       
  1272                 
       
  1273             if( iNearestTriggers[i].remRearmTime == 0 )
       
  1274                 {
       
  1275                 // It is enough for us to know the approx time required to reach nearest trigger whose 
       
  1276                 // rearm time is not zero( nearest which is not fired )  
       
  1277                 position = i;
       
  1278                 break;
       
  1279                 }
       
  1280             }
       
  1281         
       
  1282         /**
       
  1283          * Determine the sleep interval considering the rearm time of all the fired triggers.
       
  1284          * Sleep interval should be min[max[rearm time,minimum time to reach trigger]]. Flag needed
       
  1285          * for determining if movement detection is needed. Movement detector will be used if
       
  1286          * position acquisition should be made to re-activate the trigger.
       
  1287          */        
       
  1288         iSleepInterval = 0;
       
  1289         TLbtTriggerId nearestTriggerId = 0;
       
  1290         
       
  1291         // Sleep interval should be min[max[rearm time,minimum time to reach trigger]]
       
  1292         if( position >= 0 )
       
  1293             {
       
  1294             for( TInt i=0;i<=position;i++ )
       
  1295                 {
       
  1296                 // Sleep interval for a trigger is the maximum of time to trigger and rearm time
       
  1297                 TInt maxSleepTimeForTrigger;
       
  1298                 if( iNearestTriggers[i].remRearmTime < iNearestTriggers[i].minTimeRequired )
       
  1299                     {
       
  1300                     maxSleepTimeForTrigger = iNearestTriggers[i].minTimeRequired;
       
  1301                     }
       
  1302                 else
       
  1303                     {
       
  1304                     maxSleepTimeForTrigger = iNearestTriggers[i].remRearmTime;
       
  1305                     }
       
  1306                 
       
  1307                 // Sleep interval for system is minimum sleep interval of all triggers    
       
  1308                 if( ( !iSleepInterval.Int() && maxSleepTimeForTrigger ) ||
       
  1309                       iSleepInterval.Int() > maxSleepTimeForTrigger )  
       
  1310                     {
       
  1311                     iSleepInterval = maxSleepTimeForTrigger;
       
  1312                     nearestTriggerId = iNearestTriggers[i].id;
       
  1313                     }
       
  1314                 }
       
  1315             }
       
  1316         // Case where all the triggers are waiting for rearm time to elapse
       
  1317         else
       
  1318             {
       
  1319             for( TInt i=0;i<iNearestTriggers.Count();i++ )
       
  1320                 {
       
  1321                 if( !iSleepInterval.Int() || 
       
  1322                     ( iSleepInterval.Int() > iNearestTriggers[i].remRearmTime ))
       
  1323                     {
       
  1324                     iSleepInterval = iNearestTriggers[i].remRearmTime;
       
  1325                     }
       
  1326                 }
       
  1327             }  
       
  1328             
       
  1329         LOG1("Estimated speed:%f",iEstimatedUserSpeed);
       
  1330         
       
  1331         
       
  1332         if( nearestTriggerId )
       
  1333             {
       
  1334             // Update the nearestTriggerInactive flag                        
       
  1335             CLbtContainerTriggerEntry* trigEntry = NULL;
       
  1336             TBool found = iView->GetTriggerByID( nearestTriggerId, trigEntry );
       
  1337             
       
  1338             if( found && (trigEntry != NULL) )
       
  1339                 {
       
  1340                 TStrategyData strategyData = trigEntry->StrategyData();
       
  1341                 
       
  1342                 if( strategyData.iActivityStatus == EInactive )
       
  1343                     {
       
  1344                     // Inside triggering area
       
  1345                     nearestTriggerInactive = ETrue;
       
  1346                     }
       
  1347                 else
       
  1348                     {
       
  1349                     // Outside triggering area
       
  1350                     nearestTriggerInactive = EFalse;
       
  1351                     }
       
  1352                 }
       
  1353             }
       
  1354         
       
  1355         // Reduce the time taken from last position fix
       
  1356         if( iLastLocationFixType == EProperFix )
       
  1357         	{
       
  1358         	TTime currentTime;
       
  1359     	    currentTime.UniversalTime();
       
  1360     	    TTimeIntervalSeconds seconds;
       
  1361     	    currentTime.SecondsFrom(iLastFixTime, seconds);
       
  1362     	    iProcessingInterval = seconds.Int();
       
  1363     	    iSleepInterval = iSleepInterval.Int() - iProcessingInterval;
       
  1364         	}
       
  1365         }   
       
  1366     
       
  1367     // If sleep interval is less than KMinSleepInterval and the UE is travelling in
       
  1368     // high speed then request terminal position immediately
       
  1369     if( !nearestTriggerInactive &&
       
  1370         ( iSleepInterval.Int() <= KMinSleepInterval ) &&
       
  1371         ( iLastLocationFixType == EProperFix ) )
       
  1372         {
       
  1373         LOG1("Requesting time out %d", iSleepInterval.Int());
       
  1374         iFixForFiringCloseTriggers = ETrue;
       
  1375         // Here we need fix with in the estimated time to reach trigger.Hence setting timeout value to 
       
  1376         // estimated sleep interval	
       
  1377         RequestTerminalPosition( (KMinSleepInterval * KMicroMultiplier),EProperFix );
       
  1378         return;
       
  1379         }
       
  1380     
       
  1381     iState = ESleep;
       
  1382     TBool useMvmtDet = ETrue;
       
  1383     if( iLastLocationFixType != EProperFix )
       
  1384     	{
       
  1385     	useMvmtDet = ETrue;
       
  1386     	}
       
  1387     else if( nearestTriggerInactive )
       
  1388     	{
       
  1389     	useMvmtDet = ETrue;
       
  1390     	}    
       
  1391     else if( iSleepInterval.Int() < 20 )
       
  1392     	{
       
  1393     	useMvmtDet = EFalse;
       
  1394     	}
       
  1395 	else if( actualEstimatedSpeed > KMaxSpeedToUseMvmtDet )
       
  1396     	{
       
  1397     	useMvmtDet = EFalse;
       
  1398     	}
       
  1399     LOG1("useMvmtDet = %d", useMvmtDet);
       
  1400     iTimer->Set( iStatus, iSleepInterval, useMvmtDet );
       
  1401     SetActive();
       
  1402     }
       
  1403 
       
  1404     
       
  1405 // -----------------------------------------------------------------------------
       
  1406 // CLbtCoOrdinateSupervisor::ProcessInterrupt
       
  1407 // Evaluates the cause of a timer interrupt and determines the necessary 
       
  1408 // actions to be performed
       
  1409 // -----------------------------------------------------------------------------
       
  1410 //
       
  1411 void CLbtCoOrdinateSupervisor::ProcessInterrupt()
       
  1412     {
       
  1413     FUNC_ENTER("CLbtCoOrdinateSupervisor::ProcessInterrupt");
       
  1414     
       
  1415     // This is when errors occur while acquiring terminal position
       
  1416     if( !iStatusManager->LocationAcqSuccess() )
       
  1417         {
       
  1418         // Check sleep interval and determine if sleep mode can continue else 
       
  1419         // retry acquiring terminal position. This happens when there are 
       
  1420         // changes to triggers in the sleep mode during which the sleep is 
       
  1421         // cancelled and trigger view is refreshed. Once the refresh operation
       
  1422         // is completed, this method is invoked.
       
  1423         TTimeIntervalSeconds interval;
       
  1424         if( iTimer->RemainingSleepInterval( interval ) )
       
  1425             {
       
  1426             iState = ESleep;
       
  1427             if( interval.Int() < 5 )
       
  1428                 {
       
  1429                 iTimer->ResetInterval( iStatus, interval,EFalse );
       
  1430                 }
       
  1431             else
       
  1432                 {
       
  1433                 iTimer->ResetInterval( iStatus, interval,ETrue );
       
  1434                 }
       
  1435             SetActive();
       
  1436             }
       
  1437         else
       
  1438             {
       
  1439             // If the last location acqusition has failed and the location information for the current cell
       
  1440             // is unavailable then request location from NPP PSY else request from DB itself
       
  1441             if( (iLastCellRequestStatus == KErrNone) && 
       
  1442                 iLocArea.iCellId )
       
  1443 		        {
       
  1444 		        // Cell information is available
       
  1445 		        if( !(KErrNone == GetCellIdPosition( iPosInfo ) ) )
       
  1446 		        	{
       
  1447 		        	RequestTerminalPosition( iSettings.iLocationRequestTimeout, EProperFix );
       
  1448 		        	}
       
  1449 		        else
       
  1450 		            {
       
  1451 		            RequestTerminalPosition( iSettings.iLocationRequestTimeout, EFixFromDb );
       
  1452 		            }
       
  1453             	}
       
  1454             else
       
  1455             	{
       
  1456             	// Current cell information un-available. Make proper fix
       
  1457             	RequestTerminalPosition( iSettings.iLocationRequestTimeout, EProperFix );
       
  1458             	}
       
  1459         	}
       
  1460         }
       
  1461 
       
  1462     
       
  1463     // This is when sleep mode is interrupted due to notifications from 
       
  1464     // container for addition/modification/deletion of triggers in the system
       
  1465     else if( iTimer->SleepIntervalInterrupted() )
       
  1466         {
       
  1467         TLbtTriggerId nearestTrigger = 0;
       
  1468         if( iNearestTriggers.Count() )
       
  1469             {
       
  1470             for( TInt i=0;i<iNearestTriggers.Count();i++ )
       
  1471                 {
       
  1472                 if( iNearestTriggers[i].remRearmTime == 0 )
       
  1473                     {
       
  1474                     nearestTrigger = iNearestTriggers[i].id;
       
  1475                     break;
       
  1476                     }
       
  1477                 }
       
  1478             }
       
  1479         iView->DetermineNearestTriggerChanges( &iNearestTriggers );
       
  1480         
       
  1481         if( iNearestTriggers.Count() == 0 )
       
  1482             {
       
  1483             // This means the nearest 5 triggers have been changed. Reset
       
  1484             // iterator re-evaluate all triggers in the system. 
       
  1485             if( KErrNone != ResetViewIterator() )
       
  1486                 {
       
  1487                 return;
       
  1488                 }
       
  1489             iState = ETriggerEvaluation;
       
  1490             SetEvent();
       
  1491             }
       
  1492         else
       
  1493             {
       
  1494             TBool makeLocReq = EFalse;
       
  1495             TRAPD( err, makeLocReq = EvaluateModifiedTriggersL( ) );
       
  1496             
       
  1497             if( KErrNone != err )
       
  1498             	{
       
  1499             	ERROR("EvaluateTriggersL leaving with %d", err);
       
  1500 	            Term();
       
  1501 	            return;            	
       
  1502             	}
       
  1503             
       
  1504             if( makeLocReq )
       
  1505             	{
       
  1506             	// Location request is needed based on evaluating
       
  1507             	// modified triggers
       
  1508             	RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
  1509             	return;
       
  1510             	}
       
  1511             
       
  1512             // Check if nearest trigger has changed
       
  1513             TLbtTriggerId nearestTriggerAfterEvaluation = 0;
       
  1514             if( iNearestTriggers.Count() )
       
  1515                 {
       
  1516                 for( TInt i=0;i<iNearestTriggers.Count();i++ )
       
  1517                     {
       
  1518                     if( iNearestTriggers[i].remRearmTime == 0 )
       
  1519                         {
       
  1520                         nearestTriggerAfterEvaluation = iNearestTriggers[i].id;
       
  1521                         break;
       
  1522                         }
       
  1523                     }
       
  1524                 }
       
  1525             // This is check is required when all triggers in the system has fired
       
  1526             // and new trigger has been added.
       
  1527             if( (nearestTriggerAfterEvaluation) && 
       
  1528                 (nearestTrigger != nearestTriggerAfterEvaluation) )                 
       
  1529                 {
       
  1530                 RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
  1531                 }            
       
  1532             else
       
  1533                 {
       
  1534                 // Check if there be any remaining sleep interval. If true, 
       
  1535                 // then switch to sleep mode for the remaining time period. 
       
  1536                 // Else switch to acquiring location information.
       
  1537                 TTimeIntervalSeconds remainingInterval;
       
  1538                 if( iTimer->RemainingSleepInterval( remainingInterval ) )
       
  1539                     {
       
  1540                     iState = ESleep;
       
  1541                     if( remainingInterval.Int() < 5 )
       
  1542                         {
       
  1543                         iTimer->ResetInterval( iStatus, remainingInterval,EFalse ); 
       
  1544                         }
       
  1545                     else
       
  1546                         {
       
  1547                         iTimer->ResetInterval( iStatus, remainingInterval,ETrue ); 
       
  1548                         }
       
  1549                     SetActive();
       
  1550                     }
       
  1551                 else
       
  1552                     {
       
  1553                     RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
  1554                     }
       
  1555                 }
       
  1556             }
       
  1557         }        
       
  1558     else if( KErrNone == iStatus.Int() || KErrAbort == iStatus.Int() )
       
  1559         {
       
  1560         RequestTerminalPosition( iSettings.iLocationRequestTimeout );
       
  1561         }
       
  1562     else
       
  1563         {
       
  1564         LOG1("Error in timer:%d",iStatus.Int());
       
  1565         }
       
  1566     }
       
  1567     
       
  1568 
       
  1569 // -----------------------------------------------------------------------------
       
  1570 // CLbtCoOrdinateSupervisor::RequestTerminalPosition
       
  1571 // Issues an asynchronous request to determine terminal's position
       
  1572 // -----------------------------------------------------------------------------
       
  1573 //
       
  1574 void CLbtCoOrdinateSupervisor::RequestTerminalPosition( TInt aLocationRequestTimeout,
       
  1575                                                         TLocationFixType aFixLocationFixType )
       
  1576     {
       
  1577     FUNC_ENTER("CLbtCoOrdinateSupervisor::RequestTerminalPosition");
       
  1578     iPrevPosInfo = iPosInfo;
       
  1579     LOG1("aFixLocationFixType = %d", aFixLocationFixType);
       
  1580     LOG1("Cell Id = %d", iLocArea.iCellId);
       
  1581 
       
  1582     if( (aFixLocationFixType == EFixFromDb) && 
       
  1583         (iLastCellRequestStatus == KErrNone) && 
       
  1584         iLocArea.iCellId )
       
  1585         {
       
  1586         LOG("Taking fix from DB");
       
  1587         TInt error = GetCellIdPosition( iPosInfo );
       
  1588         if( KErrNone ==  error)
       
  1589             {
       
  1590             LOG("Fix From DB");
       
  1591             TPosition position;
       
  1592             iPosInfo.GetPosition(position);
       
  1593             LOG1("Lat:%f", position.Latitude());
       
  1594 			LOG1("Long:%f", position.Longitude());
       
  1595 			LOG1("HA:%f", position.HorizontalAccuracy());
       
  1596             iLastLocationFixType = EFixFromDb;
       
  1597             iState = ETriggerEvaluation;
       
  1598             SetEvent();
       
  1599             return;
       
  1600             }
       
  1601         else
       
  1602         	{
       
  1603         	LOG1("Failed to get Fix From DB with %d", error);
       
  1604         	}
       
  1605         }
       
  1606     else if( aFixLocationFixType == EFixFromNpp )
       
  1607         {
       
  1608         iLastLocationFixType = EFixFromNpp;
       
  1609         iLocationRequestor->CurrentLocationFromNpp( iPosInfo, iStatus, 
       
  1610                                                     TTimeIntervalMicroSeconds( aLocationRequestTimeout ) );
       
  1611         iState = ELocationAcquisition;
       
  1612         SetActive();
       
  1613         return;
       
  1614         }
       
  1615 
       
  1616     iLastLocationFixType = EProperFix;
       
  1617     iLocationRequestor->CurrentLocation( iPosInfo, iStatus, 
       
  1618                                             iModuleId,
       
  1619                                             TTimeIntervalMicroSeconds( aLocationRequestTimeout ) );
       
  1620     iState = ELocationAcquisition;
       
  1621     SetActive();        
       
  1622     }
       
  1623 
       
  1624 
       
  1625 // -----------------------------------------------------------------------------
       
  1626 // CLbtCoOrdinateSupervisor::GetCellIdPosition
       
  1627 // Get the position corresponding to current cell id
       
  1628 // -----------------------------------------------------------------------------
       
  1629 //
       
  1630 TInt CLbtCoOrdinateSupervisor::GetCellIdPosition( TPositionInfo& aPositionInfo )
       
  1631     {
       
  1632     FUNC_ENTER("CLbtCoOrdinateSupervisor::GetCellIdPosition");
       
  1633     TInt countryCode,networkCode;
       
  1634     
       
  1635     TLex lex( iNwInfo.iCountryCode );
       
  1636     lex.Val( countryCode );
       
  1637     
       
  1638     lex.Assign( iNwInfo.iNetworkId );
       
  1639     lex.Val( networkCode );
       
  1640     
       
  1641     TPosition position;
       
  1642     TInt error = iCellIdDatabase->GetLocationForCid( countryCode,networkCode,iLocArea.iLocationAreaCode,
       
  1643                                                      iLocArea.iCellId,position );
       
  1644     if( error == KErrNone )
       
  1645         {
       
  1646         aPositionInfo.SetPosition( position );
       
  1647         }
       
  1648     return error;    
       
  1649     }
       
  1650 
       
  1651 
       
  1652 // -----------------------------------------------------------------------------
       
  1653 // CLbtCoOrdinateSupervisor::UpdateNearestTriggers
       
  1654 // Updates the record of nearest triggers
       
  1655 // -----------------------------------------------------------------------------
       
  1656 //
       
  1657 void CLbtCoOrdinateSupervisor::UpdateNearestTriggers( TLbtTriggerId aID, TReal aDistance , TInt aRemRearmTime )
       
  1658     {
       
  1659     FUNC_ENTER("CLbtCoOrdinateSupervisor::UpdateNearestTriggers");
       
  1660     TNearestTrigger nTrigger;
       
  1661     nTrigger.distance = aDistance;
       
  1662     nTrigger.id = aID;
       
  1663     nTrigger.remRearmTime = aRemRearmTime;
       
  1664     
       
  1665     TLinearOrder< TNearestTrigger > byDistance( CompareByDistance );
       
  1666     iNearestTriggers.InsertInOrderAllowRepeats( nTrigger, byDistance );
       
  1667     }
       
  1668 
       
  1669 
       
  1670 // -----------------------------------------------------------------------------
       
  1671 // CLbtCoOrdinateSupervisor::EstimateTriggerRadii
       
  1672 // Calculcates the trigger radius and the radius of the hysteresis circle
       
  1673 // -----------------------------------------------------------------------------
       
  1674 //
       
  1675 CLbtCoOrdinateSupervisor::TTriggerArea CLbtCoOrdinateSupervisor::EstimateTriggerRadii( 
       
  1676                          TReal aTriggerRadius, TReal aHysteresisRadius,
       
  1677                          TReal aPositionAccuracy )
       
  1678     {
       
  1679     TTriggerArea trgArea;
       
  1680     TReal ratioOfCircularAreas =  aPositionAccuracy / aTriggerRadius;
       
  1681     
       
  1682     if(  ratioOfCircularAreas >= KCofftOfHighEdgeLimit )
       
  1683         {
       
  1684         trgArea.triggerRadius = aTriggerRadius;
       
  1685         trgArea.hysteresisRadius = aHysteresisRadius;
       
  1686         }
       
  1687     else
       
  1688         {
       
  1689         // Update radiusOfTrigger and radiusOfHysteresis accordingly
       
  1690         trgArea.triggerRadius = aTriggerRadius +( KAccuracyMultiplier * aPositionAccuracy );
       
  1691         trgArea.hysteresisRadius = Hysteresis( trgArea.triggerRadius );        
       
  1692         }
       
  1693         
       
  1694     return trgArea;
       
  1695     }
       
  1696 
       
  1697 
       
  1698 // -----------------------------------------------------------------------------
       
  1699 // CLbtCoOrdinateSupervisor::Hysteresis
       
  1700 // Calculates the hysteresis radius 
       
  1701 // -----------------------------------------------------------------------------
       
  1702 //
       
  1703 TReal CLbtCoOrdinateSupervisor::Hysteresis( TReal aTriggerRadius )
       
  1704     {
       
  1705     TReal hysteresis;
       
  1706     if( aTriggerRadius > KTriggerRadiusCutoff )
       
  1707         {
       
  1708         TReal logRadius;				
       
  1709         Math::Ln( logRadius, aTriggerRadius / 10 );
       
  1710         hysteresis = aTriggerRadius / logRadius;        
       
  1711         }
       
  1712     else
       
  1713         {
       
  1714         hysteresis = aTriggerRadius / 4;
       
  1715         }
       
  1716     
       
  1717     return hysteresis + aTriggerRadius;
       
  1718     }
       
  1719 
       
  1720 
       
  1721 // -----------------------------------------------------------------------------
       
  1722 // CLbtCoOrdinateSupervisor::DetermineNearestDistances
       
  1723 // Algorithm to determine the shortest distance
       
  1724 // -----------------------------------------------------------------------------
       
  1725 //
       
  1726 TInt CLbtCoOrdinateSupervisor::CompareByDistance( const TNearestTrigger& src,
       
  1727         const TNearestTrigger& dst )
       
  1728     {
       
  1729     if( src.distance > dst.distance )
       
  1730         {
       
  1731         return 1;
       
  1732         }
       
  1733     else if( src.distance < dst.distance )
       
  1734         {
       
  1735         return -1;
       
  1736         }
       
  1737     return 0;
       
  1738     }
       
  1739    
       
  1740 
       
  1741 // -----------------------------------------------------------------------------
       
  1742 // CLbtCoOrdinateSupervisor::CompareByID
       
  1743 // Determine equality of nearest triggers by id
       
  1744 // -----------------------------------------------------------------------------
       
  1745 //
       
  1746 TBool CLbtCoOrdinateSupervisor::CompareByID( const TNearestTrigger& src,
       
  1747         const TNearestTrigger& dst )
       
  1748     {
       
  1749     if( src.id > dst.id )
       
  1750         {
       
  1751         return ETrue;
       
  1752         }
       
  1753     return EFalse;
       
  1754     }
       
  1755 
       
  1756 
       
  1757 // -----------------------------------------------------------------------------
       
  1758 // CLbtCoOrdinateSupervisor::ResetViewIterator
       
  1759 // Resets trigger view iterator.
       
  1760 // -----------------------------------------------------------------------------
       
  1761 //
       
  1762 TInt CLbtCoOrdinateSupervisor::ResetViewIterator()
       
  1763     {
       
  1764     FUNC_ENTER("CLbtCoOrdinateSupervisor::ResetViewIterator");
       
  1765     TInt err = iViewIterator.Reset();
       
  1766     if( KErrNone != err )
       
  1767         {
       
  1768         if( KErrNotFound == err )
       
  1769             {
       
  1770             // determine update interval
       
  1771             iState = iProjectedState = EIdle;
       
  1772             }
       
  1773         else
       
  1774             {
       
  1775             // TODO: Report error to server. This can be done only after 
       
  1776             // introducing new state to strategy dynamic info.
       
  1777             Term();
       
  1778             }
       
  1779         return err;
       
  1780         }
       
  1781         
       
  1782     return KErrNone;
       
  1783     }
       
  1784 
       
  1785 
       
  1786 // -----------------------------------------------------------------------------
       
  1787 // CLbtCoOrdinateSupervisor::RunL
       
  1788 // Inherited from CActive - called when the request issued is completed.
       
  1789 // -----------------------------------------------------------------------------
       
  1790 //
       
  1791 void CLbtCoOrdinateSupervisor::RunL()
       
  1792     {
       
  1793     FUNC_ENTER("CLbtCoOrdinateSupervisor::RunL");
       
  1794     switch ( iState )
       
  1795         {
       
  1796         case ELocationAcquisition:
       
  1797             GetPositionInfoL();
       
  1798             break;
       
  1799 
       
  1800         case ETriggerEvaluation:
       
  1801             EvaluateTriggersL();
       
  1802             break;
       
  1803             
       
  1804         case EUpdateIntervalEstimation:
       
  1805             EstimateSleepInterval();
       
  1806             break;
       
  1807 
       
  1808         case ESleep:
       
  1809         	LOG("Wakeup");
       
  1810             ProcessInterrupt();
       
  1811             break;
       
  1812         
       
  1813         default:
       
  1814             break;
       
  1815         }
       
  1816     }
       
  1817 
       
  1818 
       
  1819 // -----------------------------------------------------------------------------
       
  1820 // CLbtCoOrdinateSupervisor::DoCancel
       
  1821 // Inherited from CActive - called to cancel outanding events.
       
  1822 // -----------------------------------------------------------------------------
       
  1823 //
       
  1824 void CLbtCoOrdinateSupervisor::DoCancel()
       
  1825     {
       
  1826     FUNC_ENTER("CLbtCoOrdinateSupervisor::DoCancel");
       
  1827     iFixForFiringCloseTriggers = EFalse;
       
  1828     }
       
  1829 
       
  1830 
       
  1831 // -----------------------------------------------------------------------------
       
  1832 // CLbtCoOrdinateSupervisor::RunError
       
  1833 // Handles the event of leave from the request completion event handler RunL()
       
  1834 // -----------------------------------------------------------------------------
       
  1835 //
       
  1836 TInt CLbtCoOrdinateSupervisor::RunError( TInt /*aError*/ ) 
       
  1837     {
       
  1838     FUNC_ENTER("CLbtCoOrdinateSupervisor::RunError");
       
  1839     Term();
       
  1840     return KErrNone;
       
  1841     }
       
  1842 
       
  1843 
       
  1844 // -----------------------------------------------------------------------------
       
  1845 // CLbtCoOrdinateSupervisor::CLbtCoOrdinateSupervisor
       
  1846 // C++ default constructor.
       
  1847 // -----------------------------------------------------------------------------
       
  1848 //
       
  1849 CLbtCoOrdinateSupervisor::CLbtCoOrdinateSupervisor() : 
       
  1850                 CActive( EPriorityHigh )
       
  1851     {
       
  1852     CActiveScheduler::Add( this );
       
  1853     }
       
  1854 
       
  1855     
       
  1856 // -----------------------------------------------------------------------------
       
  1857 // CLbtCoOrdinateSupervisor::ConstructL
       
  1858 // Symbian 2nd phase constructor.
       
  1859 // -----------------------------------------------------------------------------
       
  1860 //
       
  1861 void CLbtCoOrdinateSupervisor::ConstructL( TAny* /*aConstructionParameters*/,
       
  1862                                            CLbtTriggerView* aView,
       
  1863                                            MLbtStrategyEngineObsrvr* aObserver,
       
  1864                                            CLbtCellChangeHandler* aCellChangeHandler )
       
  1865     {
       
  1866 	iEngObserver = aObserver;
       
  1867 	iState = iProjectedState = EIdle;
       
  1868 	iEngObserver->RetrieveTriggeringSettings( iSettings );
       
  1869 	iCellChangeHandler = aCellChangeHandler;
       
  1870   
       
  1871     iModuleId = iSettings.iPositioningTechnology;
       
  1872     
       
  1873 	iLocationRequestor = CLbtLocationRequestor::NewL();
       
  1874 	
       
  1875 	iStatusManager = CLbtStatusManager::NewL();
       
  1876 	iTimer = CLbtStrategyTimer::NewL();
       
  1877 	iView = aView;	
       
  1878 	
       
  1879 	iViewIterator = iView->BeginL( CLbtGeoAreaBase::ECircle );
       
  1880 	iCellIdDatabase = CLbtCellIdDatabase::NewL();
       
  1881 	iLastCellRequestStatus = KErrUnknown;
       
  1882 	iLastLocationFixType = EFixUnknown;
       
  1883 	iPsyChangeListner = NULL;
       
  1884 	iFixForFiringCloseTriggers = EFalse;
       
  1885     }
       
  1886     
       
  1887 
       
  1888 // -----------------------------------------------------------------------------
       
  1889 // CLbtCoOrdinateSupervisor::SetEvent
       
  1890 // Completes the iRequestStatus with KErrNone.
       
  1891 // -----------------------------------------------------------------------------
       
  1892 //
       
  1893 void CLbtCoOrdinateSupervisor::SetEvent()
       
  1894     {
       
  1895     if ( !IsActive() )
       
  1896     	{
       
  1897     	TRequestStatus* lStatus = &iStatus;
       
  1898     	User::RequestComplete( lStatus, KErrNone );
       
  1899         SetActive();
       
  1900     	}    
       
  1901     }
       
  1902 
       
  1903 
       
  1904 // -----------------------------------------------------------------------------
       
  1905 // CLbtCoOrdinateSupervisor::Term
       
  1906 // 
       
  1907 // -----------------------------------------------------------------------------
       
  1908 //
       
  1909 void CLbtCoOrdinateSupervisor::Term()
       
  1910     {
       
  1911     FUNC_ENTER("CLbtCoOrdinateSupervisor::Term");
       
  1912     
       
  1913     iSupervisionInitiated = EFalse;
       
  1914             
       
  1915     iView->Cancel();
       
  1916     switch( iState )
       
  1917         {
       
  1918     case ELocationAcquisition:
       
  1919         if( iLastLocationFixType == EProperFix )
       
  1920     		{
       
  1921     		iLocationRequestor->Cancel();
       
  1922     		}
       
  1923     	else
       
  1924     		{
       
  1925     		iLocationRequestor->CancelFixFromNpp();
       
  1926     		}
       
  1927         break;
       
  1928         
       
  1929     case ESleep:
       
  1930         iTimer->Cancel();
       
  1931         break;
       
  1932     
       
  1933     default:
       
  1934         Cancel();
       
  1935         break;
       
  1936         }
       
  1937         
       
  1938     iState = iProjectedState = EIdle;
       
  1939     iLastLocationFixType = EFixUnknown;
       
  1940     iFixForFiringCloseTriggers = EFalse;
       
  1941     }
       
  1942 
       
  1943 // -----------------------------------------------------------------------------
       
  1944 // CLbtCoOrdinateSupervisor::FireClosestTriggers
       
  1945 // 
       
  1946 // -----------------------------------------------------------------------------
       
  1947 //
       
  1948 void CLbtCoOrdinateSupervisor::FireClosestTriggers()
       
  1949 	{
       
  1950 	FUNC_ENTER("CLbtCoOrdinateSupervisor::FireClosestTriggers");
       
  1951 	LOG1("NT Count = %d", iNearestTriggers.Count());
       
  1952 	for( TInt i=0;i<iNearestTriggers.Count();i++ )
       
  1953 		{
       
  1954 		if(iNearestTriggers[i].remRearmTime != 0)
       
  1955 		    {
       
  1956 		    continue;
       
  1957 		    }
       
  1958 
       
  1959 		TInt timeToTrigger = (iNearestTriggers[i].distance / iEstimatedUserSpeed);		
       
  1960 
       
  1961         TInt estimatedInterval = timeToTrigger - iProcessingInterval;
       
  1962 
       
  1963 		LOG1("estimatedInterval = %d", estimatedInterval);
       
  1964 
       
  1965 		if( estimatedInterval <= KMinSleepInterval )
       
  1966 			{
       
  1967 			LOG("NEED TO FIRE");
       
  1968 			CLbtContainerTriggerEntry* trigger;
       
  1969 			if( iView->GetTriggerByID( iNearestTriggers[i].id,trigger ) )
       
  1970 				{
       
  1971 				LOGSTRING("Trigger: \"%S\" ", &(trigger->TriggerEntry()->Name()));
       
  1972 				// check the activity status
       
  1973 				TStrategyData strategyData = trigger->StrategyData();   
       
  1974 				if( strategyData.iActivityStatus == EActive )
       
  1975 				    {
       
  1976 				    // Fire the trigger
       
  1977                     TLbtTriggerDataMask dataMask = 0;
       
  1978                     
       
  1979                     // Set trigger state to fired
       
  1980                     trigger->ExtendedTriggerInfo()->SetTriggerFiredState( ETrue );
       
  1981                     TLbtTriggerFireInfo triggerFireInfo;
       
  1982                     TPositionInfo positionInfo;
       
  1983                     triggerFireInfo.iTriggerId = trigger->TriggerEntry()->Id();
       
  1984                     triggerFireInfo.iFiredPositionInfo = iPrevPosInfo;
       
  1985                     
       
  1986                     trigger->ExtendedTriggerInfo()->SetFiredInfo( triggerFireInfo );
       
  1987                     
       
  1988                     // Time at which trigger fired
       
  1989                     TTime triggerFiredTime;
       
  1990                     triggerFiredTime.UniversalTime();
       
  1991                     LOG("NEAREST TRIGGER FIRED");
       
  1992                     
       
  1993                     strategyData.iFireTime = triggerFiredTime.Int64();
       
  1994                     // Set trigger to inactive state
       
  1995                     strategyData.iActivityStatus = EInactive;
       
  1996                     
       
  1997                     dataMask |= 
       
  1998                     CLbtContainerTriggerEntry::EContainerAttributeIsFired | 
       
  1999                     CLbtContainerTriggerEntry::EContainerAttributeFireInfo ;
       
  2000                     
       
  2001                     iView->UpdateTriggerInfo( CLbtGeoAreaBase::ECircle,iPosInfo, trigger, dataMask );
       
  2002                     trigger->SetStrategyData( strategyData );
       
  2003 				    }
       
  2004                 }
       
  2005             else
       
  2006                 {
       
  2007                 LOG("TRIGGER NOT FOUND ??");
       
  2008                 }
       
  2009 			}
       
  2010 		else
       
  2011 			{
       
  2012 			LOG("ELSE");
       
  2013 			// Since the array is in the ascending order of distance( which is directly proportional to time ),
       
  2014 			// we can need not search rest of the array.	
       
  2015 			break;
       
  2016 			}					
       
  2017 		}
       
  2018 	}
       
  2019 
       
  2020 // -----------------------------------------------------------------------------
       
  2021 // CLbtCoOrdinateSupervisor::CalculateTolerableRadius
       
  2022 // 
       
  2023 // -----------------------------------------------------------------------------
       
  2024 //
       
  2025 TReal CLbtCoOrdinateSupervisor::CalculateTolerableRadius( TReal aRadius )
       
  2026     {
       
  2027     // Tolerance can be calculated using the straight line equation. Slope of straight line is 0.07 and 
       
  2028     // intercept is 22.2
       
  2029     TReal tolerableInaccuracy = ( 0.07 * aRadius ) + 22.2;
       
  2030     return ( tolerableInaccuracy + aRadius );
       
  2031     }
       
  2032 
       
  2033 // -----------------------------------------------------------------------------
       
  2034 // CLbtCoOrdinateSupervisor::HandleCellChangeEvent
       
  2035 // 
       
  2036 // -----------------------------------------------------------------------------
       
  2037 //
       
  2038 void CLbtCoOrdinateSupervisor::HandleCellChangeEvent(
       
  2039             const TInt aStatus,
       
  2040             const RMobilePhone::TMobilePhoneNetworkInfoV1& aNwInfo,
       
  2041             const RMobilePhone::TMobilePhoneLocationAreaV1& aLocArea)
       
  2042     {
       
  2043     FUNC_ENTER("CLbtCoOrdinateSupervisor::HandleCellChangeEvent");
       
  2044     if( KErrNone == aStatus )
       
  2045 	    {
       
  2046 	    // validate network info
       
  2047 		if (aNwInfo.iMode == RMobilePhone::ENetworkModeGsm ||
       
  2048             aNwInfo.iMode == RMobilePhone::ENetworkModeWcdma)
       
  2049             {
       
  2050             TLex lex( aNwInfo.iCountryCode );
       
  2051             TInt countryCode,networkCode;
       
  2052             lex.Val( countryCode );
       
  2053             if( countryCode )
       
  2054                 {
       
  2055                 lex.Assign( aNwInfo.iNetworkId );
       
  2056                 lex.Val( networkCode );
       
  2057                 if( networkCode )
       
  2058                     {
       
  2059                     if( aLocArea.iLocationAreaCode && aLocArea.iCellId )
       
  2060                         {
       
  2061                         iLastCellRequestStatus = KErrNone;
       
  2062                         iNwInfo = aNwInfo;
       
  2063 		                iLocArea = aLocArea;
       
  2064 		                }
       
  2065                     }
       
  2066                 }
       
  2067             }
       
  2068 		}
       
  2069 	else 
       
  2070 	    {
       
  2071 	    iLastCellRequestStatus = aStatus;
       
  2072 	    }	
       
  2073     }
       
  2074 
       
  2075 // -----------------------------------------------------------------------------
       
  2076 // CLbtCoOrdinateSupervisor::HandlePsyChangeEvent
       
  2077 // 
       
  2078 // -----------------------------------------------------------------------------
       
  2079 //
       
  2080 void CLbtCoOrdinateSupervisor::HandlePsyChangeEvent( TPositionModuleId aModuleId  )
       
  2081     {
       
  2082     LOG("CLbtCoOrdinateSupervisor::HandlePsyChangeEvent");
       
  2083     if( aModuleId == iSettings.iPositioningTechnology )
       
  2084         {
       
  2085         LOG("aModuleId == iSettings.iPositioningTechnology");
       
  2086         iModuleId = aModuleId;
       
  2087         delete iPsyChangeListner;
       
  2088         iPsyChangeListner = NULL;        
       
  2089         }
       
  2090     else
       
  2091         {
       
  2092         LOG("aModuleId != iSettings.iPositioningTechnology");
       
  2093         // We will use defualt proxy
       
  2094         iModuleId = TUid::Uid(0xFFFFFFFF);
       
  2095         iPsyChangeListner->StartToListen( iSettings.iPositioningTechnology );
       
  2096         }
       
  2097     
       
  2098     // If coordinate supervisor AO is not active,request terminal position    
       
  2099     if( !IsActive() )
       
  2100         {
       
  2101         RequestTerminalPosition( iSettings.iLocationRequestTimeout,EProperFix );
       
  2102         }    
       
  2103     }
       
  2104 // end of file