locationtriggering/ltcellidmovementdetector/src/lbtcellidmvmtdet.cpp
changeset 0 667063e416a2
child 39 3efc7a0e8755
equal deleted inserted replaced
-1:000000000000 0:667063e416a2
       
     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:  Definition of CLbtCellIdMvmtDet class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <ecom.h>
       
    21 #include <e32math.h>
       
    22 #include <implementationproxy.h>
       
    23 #include "lbtcellidmvmtdet.h"
       
    24 #include "lbtlogger.h"
       
    25 
       
    26 
       
    27 // ECOM implementation specifics
       
    28 static const TImplementationProxy implTable[] =
       
    29 	{
       
    30     IMPLEMENTATION_PROXY_ENTRY(0x2002130D, CLbtCellIdMvmtDet::NewL)
       
    31 	}; 
       
    32 
       
    33 
       
    34 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
    35     {
       
    36     aTableCount = sizeof(implTable) / sizeof(TImplementationProxy);
       
    37 
       
    38     return implTable;
       
    39     }
       
    40  
       
    41 
       
    42 // Class methods
       
    43 
       
    44 //------------------------------------------------------------
       
    45 // CLbtCellIdMvmtDet::NewL
       
    46 // Symbian Two - phase constructor
       
    47 //------------------------------------------------------------
       
    48 //
       
    49 CLbtCellIdMvmtDet* CLbtCellIdMvmtDet::NewL()
       
    50 	{
       
    51 	FUNC_ENTER("CLbtCellIdMvmtDet::NewL");
       
    52 	CLbtCellIdMvmtDet* self = new (ELeave) CLbtCellIdMvmtDet();
       
    53 	CleanupStack::PushL(self);
       
    54 	self->ConstructL();
       
    55 	CleanupStack::Pop();
       
    56 	return self;
       
    57 	}
       
    58 
       
    59 
       
    60 //------------------------------------------------------------
       
    61 // CLbtCellIdMvmtDet::ConstructL
       
    62 //------------------------------------------------------------
       
    63 //
       
    64 void CLbtCellIdMvmtDet::ConstructL()
       
    65 	{
       
    66 	FUNC_ENTER("CLbtCellIdMvmtDet::ConstructL");
       
    67 	InitializeL();
       
    68 	
       
    69 	iCellIdMvmtDetGetCellData=CLbtCellIdMvmtDetGetCellData::
       
    70 									NewL( *this ,iCApi );
       
    71 	iPreviousNetworkMode = RMmCustomAPI::TMmCellInfo::EUnknown;
       
    72 	iCurrentCellInfo = NULL;
       
    73 	iWcdmaCellInfo = NULL;	
       
    74 	iInitialCellInfo = NULL;
       
    75 	iPrevCellInfo = NULL;
       
    76 	}
       
    77 
       
    78 
       
    79 //------------------------------------------------------------
       
    80 // CLbtCellIdMvmtDet::CLbtCellIdMvmtDet
       
    81 // C++ Default constructor
       
    82 //------------------------------------------------------------
       
    83 //
       
    84 CLbtCellIdMvmtDet::CLbtCellIdMvmtDet()
       
    85 	{
       
    86 	}
       
    87 
       
    88 
       
    89 //------------------------------------------------------------
       
    90 // CLbtCellIdMvmtDet::~CLbtCellIdMvmtDet
       
    91 // Destructor
       
    92 //------------------------------------------------------------
       
    93 //
       
    94 CLbtCellIdMvmtDet::~CLbtCellIdMvmtDet()
       
    95 	{
       
    96 	FUNC_ENTER("CLbtCellIdMvmtDet::~CLbtCellIdMvmtDet");
       
    97 	delete iCellIdMvmtDetGetCellData;
       
    98     delete iPrevCellInfo;
       
    99     delete iCurrentCellInfo;
       
   100     delete iWcdmaCellInfo;
       
   101 	iCApi.Close();
       
   102     iMPhone.Close();
       
   103    	iTelServer.Close();
       
   104    	iVarianceOfED.Close();
       
   105    	iED.Close();
       
   106    	iSumOfSd.Close();
       
   107    	iVarianceOfRssi.Close();
       
   108 	}
       
   109 
       
   110 
       
   111 //------------------------------------------------------------
       
   112 // CLbtCellIdMvmtDet::RequestNotificationL
       
   113 //------------------------------------------------------------
       
   114 //	
       
   115 void CLbtCellIdMvmtDet::RequestNotificationL( MLbtMovementObserver* aObserver ,
       
   116                                                                 TInt aSleepDuration )
       
   117 	{
       
   118 	FUNC_ENTER("CLbtCellIdMvmtDet::RequestNotificationL");
       
   119 	iObserver = aObserver;
       
   120 	iSleepDuration = aSleepDuration;
       
   121 	iStartTime.UniversalTime();
       
   122 	GetCellInfo();	
       
   123 	}
       
   124 
       
   125 	
       
   126 //------------------------------------------------------------
       
   127 // CLbtCellIdMvmtDet::GetCellInfo
       
   128 //------------------------------------------------------------
       
   129 //	
       
   130 void CLbtCellIdMvmtDet::GetCellInfo()
       
   131 	{
       
   132 	FUNC_ENTER("CLbtCellIdMvmtDet::GetCellInfo");
       
   133    	iCellIdMvmtDetGetCellData->Start();
       
   134 	}
       
   135 
       
   136 
       
   137 //------------------------------------------------------------
       
   138 // CLbtCellIdMvmtDet::HandleCellDataL
       
   139 //------------------------------------------------------------
       
   140 //	
       
   141 void CLbtCellIdMvmtDet::HandleCellDataL( RMmCustomAPI::TMmCellInfo& aCellInfo, TInt& aError )
       
   142 	{
       
   143 	FUNC_ENTER("CLbtCellIdMvmtDet::HandleCellDataL");
       
   144 	if( KErrNone == aError )
       
   145 	    {
       
   146 	    if( iPreviousNetworkMode != aCellInfo.iMode && 
       
   147 	        iPreviousNetworkMode != RMmCustomAPI::TMmCellInfo::EUnknown )
       
   148 	        {
       
   149 	        LOG("Network change movement");
       
   150 	        iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   151 	        iPreviousNetworkMode = RMmCustomAPI::TMmCellInfo::EUnknown;
       
   152 	        if( iPreviousNetworkMode == RMmCustomAPI::TMmCellInfo::EWCDMA )
       
   153 	            {
       
   154 	            iVarianceOfRssi.Reset();
       
   155                 iSumOfSd.Reset();
       
   156                 }
       
   157 	        else if( iPreviousNetworkMode == RMmCustomAPI::TMmCellInfo::EGSM )
       
   158 	            {
       
   159 	            iVarianceOfED.Reset();
       
   160 	            iED.Reset();
       
   161 	            }
       
   162 	        return;
       
   163 	        }
       
   164 	    iPreviousNetworkMode = aCellInfo.iMode;    
       
   165 	    switch( aCellInfo.iMode )
       
   166 	        {
       
   167 	        case RMmCustomAPI::TMmCellInfo::EGSM:
       
   168 	            HandleGsmDataL( aCellInfo );
       
   169 	            break;
       
   170 	        
       
   171 	        case RMmCustomAPI::TMmCellInfo::EWCDMA:
       
   172 	            HandleWcmdaDataL( aCellInfo );
       
   173 	            break;
       
   174 	        
       
   175 	        default:
       
   176 	            break;    
       
   177 	        }
       
   178 	    }
       
   179 	else
       
   180 	    {
       
   181 	    iObserver->HandleDetectorNotification(MLbtMovementObserver::EEventDetectorFailed); 
       
   182 	    iVarianceOfED.Reset();
       
   183 	    iED.Reset();
       
   184         LBT_TRACE( KLbtLogCellIdMovementDetector|KLbtLogVerbose, __FILE__, __LINE__, "Movement detection failed" ); 
       
   185 	    }    
       
   186 	}
       
   187 
       
   188 //------------------------------------------------------------
       
   189 // CLbtCellIdMvmtDet::HandleGsmDataL
       
   190 //------------------------------------------------------------
       
   191 //	
       
   192 void CLbtCellIdMvmtDet::HandleGsmDataL( RMmCustomAPI::TMmCellInfo& aCellInfo )
       
   193 	{
       
   194 	FUNC_ENTER("CLbtCellIdMvmtDet::HandleGsmDataL");
       
   195 	CLbtCellInfo* cellInfo = CLbtCellInfo::NewL( aCellInfo );
       
   196     if( NULL != iPrevCellInfo )     // First iteration
       
   197         {
       
   198         // This part of algo detects short movement
       
   199         if( iSleepDuration < 20 )
       
   200             {
       
   201             if( iCurrentCellInfo )
       
   202                 {
       
   203                 delete iCurrentCellInfo;
       
   204                 iCurrentCellInfo = NULL;
       
   205                 }
       
   206             iCurrentCellInfo = cellInfo;
       
   207             DetectShortGsmMovement();
       
   208             return;
       
   209             }
       
   210         else
       
   211             {
       
   212             // Check whether sleep interval has expired
       
   213             TTime currentTime;
       
   214             currentTime.UniversalTime();
       
   215             TTimeIntervalSeconds interval;
       
   216             currentTime.SecondsFrom( iStartTime,interval );
       
   217             if( interval.Int() >= iSleepDuration )
       
   218                 {
       
   219                 // Clear all data
       
   220                 iVarianceOfED.Reset();
       
   221     	        iED.Reset();
       
   222     	        
       
   223                 delete iPrevCellInfo;
       
   224                 iPrevCellInfo = cellInfo;
       
   225                 CheckBsicVariation();
       
   226                 return;
       
   227                 }
       
   228                 
       
   229             // if there are less than 3 visible BTSs then
       
   230             // discard the reading and try acquiring new 
       
   231             // info without timer.
       
   232             if( cellInfo->Count() < 3 )
       
   233                 {
       
   234                 delete cellInfo;
       
   235                 return;
       
   236                 }
       
   237             else
       
   238                 {
       
   239                 TReal ed = 0.0;
       
   240                 if( KErrNotFound != ComputeED( ed, cellInfo, iPrevCellInfo ) )
       
   241                     {
       
   242                     iED.Append( ed );
       
   243                     iSumOfED += ed;
       
   244                     if( iED.Count() == 5 )
       
   245                         {
       
   246                         ComputeVarianceOfED();
       
   247                         if( iAvgOfVariance > 5.0 )
       
   248                             {
       
   249                             LOG1("iAvgOfVariance:%f",iAvgOfVariance);
       
   250                             iAvgOfVariance = 0.0;   // reset variance
       
   251                             iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   252                             iVarianceOfED.Reset();
       
   253     	                    iED.Reset();
       
   254                             LBT_TRACE( KLbtLogCellIdMovementDetector|KLbtLogVerbose, __FILE__, __LINE__, "Movement detected" );
       
   255                             delete cellInfo;
       
   256                             return;
       
   257                             }
       
   258                         }
       
   259                     }
       
   260                 else    // No matches found!!
       
   261                     {
       
   262                     iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   263                     iVarianceOfED.Reset();
       
   264     	            iED.Reset();
       
   265                     LBT_TRACE( KLbtLogCellIdMovementDetector|KLbtLogVerbose, __FILE__, __LINE__, "Possible movement" );
       
   266                     delete cellInfo;
       
   267                     return;
       
   268                     }
       
   269                 }
       
   270             
       
   271             delete iPrevCellInfo;
       
   272             iPrevCellInfo = NULL;
       
   273             }    
       
   274         }
       
   275     else
       
   276         {
       
   277         iInitialCellInfo = CLbtCellInfo::NewL( aCellInfo );
       
   278         }
       
   279     iPrevCellInfo = cellInfo;
       
   280     }
       
   281 
       
   282 
       
   283 //------------------------------------------------------------
       
   284 // CLbtCellIdMvmtDet::HandleWcmdaDataL
       
   285 //------------------------------------------------------------
       
   286 //	
       
   287 void CLbtCellIdMvmtDet::HandleWcmdaDataL( RMmCustomAPI::TMmCellInfo& aCellInfo )
       
   288     {
       
   289     FUNC_ENTER("CLbtCellIdMvmtDet::HandleWcmdaDataL");
       
   290     if( !iWcdmaCellInfo )
       
   291         {
       
   292         iWcdmaCellInfo = CLbtCellInfo::NewL( aCellInfo );
       
   293         }
       
   294     else
       
   295         {
       
   296         iWcdmaCellInfo->AddNMRData( aCellInfo );
       
   297         if( iSleepDuration < 20 )
       
   298             {
       
   299             DetectShortWcdmaMovement();
       
   300             return;
       
   301             }
       
   302         
       
   303         // If the total number of cell change is greater than two,we predict movement 
       
   304         // irrespective of other NMR readings.
       
   305         if( iWcdmaCellInfo->CellChangeCount() == 2 )
       
   306             {
       
   307             LOG("Cell change movement");
       
   308             iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   309             LBT_TRACE( KLbtLogCellIdMovementDetector|KLbtLogVerbose, __FILE__, __LINE__, "Movement detected" );
       
   310             iVarianceOfRssi.Reset();
       
   311             iSumOfSd.Reset();
       
   312             return;
       
   313             }
       
   314         // Check for movement based on calculation for every 10 readings
       
   315         else if( iWcdmaCellInfo->Count() == 10 )
       
   316             {
       
   317             TReal carrierRSSISD = 0.0;
       
   318         	TReal cpichEcN0SD= 0.0;
       
   319         	TReal cpichRscpSD= 0.0;
       
   320         	TReal pathlossSD= 0.0;
       
   321         	TInt cellChangeCount;
       
   322             CalculateSDForWcdmaNmr( carrierRSSISD,cpichEcN0SD,cpichRscpSD,pathlossSD,cellChangeCount );
       
   323             
       
   324             // Test log
       
   325             LOG1("carrierRSSISD:%f",carrierRSSISD);
       
   326             LOG1("cpichEcN0SD:%f",cpichEcN0SD);
       
   327             LOG1("cpichRscpSD:%f",cpichRscpSD);
       
   328             LOG1("pathlossSD:%f",pathlossSD);
       
   329             LOG1("cellChangeCount:%d",cellChangeCount);
       
   330             // Test logs
       
   331             
       
   332             // There is a possibility that network fails and it transmits stored values, it is 
       
   333             // not possible for movement detector to predict anything from the network information.Hence 
       
   334             // movement detection fails.
       
   335             if( !cpichEcN0SD || !cpichRscpSD || !pathlossSD)
       
   336                 {
       
   337                 iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventDetectorFailed ); 
       
   338                 iVarianceOfRssi.Reset();
       
   339                 iSumOfSd.Reset();
       
   340                 return;
       
   341                 }
       
   342             
       
   343             if( MovementDetected( carrierRSSISD,cpichEcN0SD,cpichRscpSD,pathlossSD,cellChangeCount ) )
       
   344                 {
       
   345                 iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   346                 iVarianceOfRssi.Reset();
       
   347                 iSumOfSd.Reset();
       
   348                 }
       
   349             }
       
   350         }    
       
   351     }
       
   352 
       
   353 //------------------------------------------------------------
       
   354 // CLbtCellIdMvmtDet::MovementDetected
       
   355 //------------------------------------------------------------
       
   356 //	
       
   357 TBool CLbtCellIdMvmtDet::MovementDetected( TReal& aCarrierRSSISD,TReal& aCpichEcN0SD,
       
   358                                            TReal& aCpichRscpSD,TReal& aPathlossSD,
       
   359                                            TInt& /*aCellChangeCount*/  )    
       
   360     {
       
   361     FUNC_ENTER("CLbtCellIdMvmtDet::MovementDetected");
       
   362     TReal sumOfSd = aCpichEcN0SD + aCpichRscpSD + aPathlossSD;
       
   363     
       
   364     if( // These 3 parameters vary for movement
       
   365         aCpichEcN0SD > 5 || 
       
   366         aCpichRscpSD > 5 ||
       
   367         aPathlossSD  > 5 ||
       
   368         aCarrierRSSISD > 3 || 
       
   369         sumOfSd > 10   ||
       
   370         ( aCarrierRSSISD > 2 && sumOfSd > 6 ) )
       
   371         {
       
   372         LOG("Reason:1");
       
   373         return ETrue;
       
   374         }
       
   375         
       
   376     iSumOfSd.Append( sumOfSd );
       
   377     iVarianceOfRssi.Append( aCarrierRSSISD );
       
   378     if( iSumOfSd.Count() == 3 )
       
   379         {
       
   380         TReal sumAvg = 0.0;
       
   381         TReal rssiAvg = 0.0;
       
   382         for( TInt i=0;i<iSumOfSd.Count();i++ )
       
   383             {
       
   384             sumAvg+= iSumOfSd[i];
       
   385             rssiAvg+= iVarianceOfRssi[i];  
       
   386             }
       
   387         sumAvg/= iSumOfSd.Count();
       
   388         rssiAvg/= iVarianceOfRssi.Count();  
       
   389         
       
   390         // Remove the old values
       
   391         iSumOfSd.Remove( 0 );
       
   392         iVarianceOfRssi.Remove( 0 );  
       
   393         
       
   394         if( ( sumAvg>6 && rssiAvg>2 ) ||
       
   395             ( sumAvg>8 && rssiAvg>1.75 ) )
       
   396             {
       
   397             LOG("Reason:2");
       
   398             return ETrue;
       
   399             }
       
   400         }
       
   401     return EFalse;    
       
   402     }
       
   403 
       
   404 //------------------------------------------------------------
       
   405 // CLbtCellIdMvmtDet::CalculateVariance
       
   406 //------------------------------------------------------------
       
   407 //	
       
   408 void CLbtCellIdMvmtDet::CalculateSDForWcdmaNmr(TReal& aCarrierRSSISD,TReal& aCpichEcN0SD,
       
   409                                                TReal& aCpichRscpSD,TReal& aPathlossSD,
       
   410                                                TInt& aCellChangeCount )
       
   411     {
       
   412     FUNC_ENTER("CLbtCellIdMvmtDet::CalculateSDForWcdmaNmr");
       
   413     TReal carrierRSSIMean = 0.0;
       
   414 	TReal cpichEcN0Mean= 0.0;
       
   415 	TReal cpichRscpMean= 0.0;
       
   416 	TReal pathlossMean= 0.0;
       
   417 	
       
   418 	// Calculate the mean for NMR values. 
       
   419 	CLbtCellInfo::TCellInfoArrayIterator iter = iWcdmaCellInfo->Begin();
       
   420 	TWcdmaNMR wcdmaNMR;
       
   421 	while( iter.Next( wcdmaNMR ) )
       
   422 	    {
       
   423 	    carrierRSSIMean+= wcdmaNMR.iCarrierRSSI;
       
   424 	    cpichEcN0Mean+= wcdmaNMR.iCpichEcN0;
       
   425 	    cpichRscpMean+= wcdmaNMR.iCpichRscp;
       
   426 	    pathlossMean+= wcdmaNMR.iPathloss;
       
   427 	    }
       
   428 	carrierRSSIMean/= iWcdmaCellInfo->Count();
       
   429     cpichEcN0Mean/= iWcdmaCellInfo->Count();
       
   430     cpichRscpMean/= iWcdmaCellInfo->Count();
       
   431     pathlossMean/= iWcdmaCellInfo->Count();
       
   432     
       
   433     // Calculate the variance for NMR values. 
       
   434     
       
   435     iter.Reset();
       
   436 	while( iter.Next( wcdmaNMR ) )
       
   437         {
       
   438         aCarrierRSSISD+= ( carrierRSSIMean - wcdmaNMR.iCarrierRSSI ) * ( carrierRSSIMean - wcdmaNMR.iCarrierRSSI );
       
   439         aCpichEcN0SD+= ( cpichEcN0Mean - wcdmaNMR.iCpichEcN0 ) * ( cpichEcN0Mean - wcdmaNMR.iCpichEcN0 );
       
   440         aCpichRscpSD+= ( cpichRscpMean - wcdmaNMR.iCpichRscp ) * ( cpichRscpMean - wcdmaNMR.iCpichRscp );
       
   441         aPathlossSD+= ( pathlossMean - wcdmaNMR.iPathloss ) * ( pathlossMean - wcdmaNMR.iPathloss );
       
   442         }
       
   443     aCarrierRSSISD/= iWcdmaCellInfo->Count();
       
   444     aCpichEcN0SD/= iWcdmaCellInfo->Count();
       
   445     aCpichRscpSD/= iWcdmaCellInfo->Count();
       
   446     aPathlossSD/= iWcdmaCellInfo->Count();
       
   447     
       
   448     // Calculate the standard deviation for NMR values.    
       
   449     Math::Sqrt( aCarrierRSSISD,aCarrierRSSISD );
       
   450     Math::Sqrt( aCpichEcN0SD,aCpichEcN0SD );
       
   451     Math::Sqrt( aCpichRscpSD,aCpichRscpSD );
       
   452     Math::Sqrt( aPathlossSD,aPathlossSD );
       
   453     
       
   454     aCellChangeCount = iWcdmaCellInfo->CellChangeCount();
       
   455     iWcdmaCellInfo->Reset();
       
   456     }
       
   457 
       
   458 	
       
   459 //------------------------------------------------------------
       
   460 // CLbtCellIdMvmtDet::ComputeED
       
   461 //------------------------------------------------------------
       
   462 //	
       
   463 TInt CLbtCellIdMvmtDet::ComputeED( TReal& aED, CLbtCellInfo* aCurrCellInfo, CLbtCellInfo* aPrevCellInfo )
       
   464     {
       
   465     FUNC_ENTER("CLbtCellIdMvmtDet::ComputeED");
       
   466     // Find matches and calculate ED
       
   467     // Compare cellinfo with the previous readings. If there are 
       
   468     // less than 3 and more than 1 matches substitute with the lower 
       
   469     // readings of RxLEV. If there is just 1 or no matches then notify 
       
   470     // movement.
       
   471     CLbtCellInfo::TCellInfoArrayIterator iter = aCurrCellInfo->Begin();
       
   472     TGsmNMR nmr;
       
   473     TInt pos = 0;
       
   474     TInt leastRxLEV = -1;
       
   475     TReal diffSqr;
       
   476     RArray< TUint > diffArray;
       
   477     RArray< TUint > posArray;
       
   478     while( iter.Next( nmr ) )
       
   479         {
       
   480         // Find least of RxLEVs in the recent measurement.
       
   481         if( -1 == leastRxLEV || nmr.RxLEV < leastRxLEV )
       
   482             {
       
   483             leastRxLEV = nmr.RxLEV;
       
   484             }
       
   485             
       
   486         if( aPrevCellInfo->Find( pos, nmr ) )
       
   487             {
       
   488             // Calculate difference in RxLEV and the corresponding square
       
   489             TInt diff = 
       
   490                 ( ( aPrevCellInfo->GetNMR() )[pos].RxLEV ) - ( nmr.RxLEV );
       
   491             Math::Pow( diffSqr, diff, 2 );
       
   492             diffArray.Append( diffSqr );
       
   493             posArray.Append( pos );
       
   494             }
       
   495         else
       
   496             {
       
   497             TInt diff = nmr.RxLEV - leastRxLEV;
       
   498             Math::Pow( diffSqr, diff, 2 );
       
   499             diffArray.Append( diffSqr );
       
   500             }
       
   501         }
       
   502     
       
   503     if( posArray.Count() > 1 )  // There was at least 1 match between the 2 readings
       
   504         {
       
   505         // Check for other lost entries in previously obtained
       
   506         // cellinfo
       
   507         RArray< TGsmNMR >& prevNMR = aPrevCellInfo->GetNMR();
       
   508         for( TInt index = 0; index < prevNMR.Count(); index++ )
       
   509             {
       
   510             if( KErrNotFound == posArray.Find( index ) )
       
   511                 {
       
   512                 TInt diff = prevNMR[index].RxLEV - leastRxLEV;
       
   513                 Math::Pow( diffSqr, diff, 2 );
       
   514                 diffArray.Append( diffSqr );
       
   515                 }
       
   516             }
       
   517            
       
   518         // Calculate ED
       
   519         TUint sum = 0;
       
   520         for( TInt index = 0; index < diffArray.Count(); index++ )
       
   521             {
       
   522             sum += diffArray[index];
       
   523             }
       
   524             
       
   525         Math::Sqrt( aED, sum );
       
   526         diffArray.Close();
       
   527         posArray.Close();
       
   528         return KErrNone;
       
   529         }
       
   530         
       
   531     return KErrNotFound;    // no matches found
       
   532     }
       
   533     
       
   534 
       
   535 //------------------------------------------------------------
       
   536 // CLbtCellIdMvmtDet::ComputeVarianceOfED
       
   537 //------------------------------------------------------------
       
   538 //	
       
   539 void CLbtCellIdMvmtDet::ComputeVarianceOfED()
       
   540     {
       
   541     FUNC_ENTER("CLbtCellIdMvmtDet::ComputeVarianceOfED");
       
   542     // Determine mean
       
   543     TReal mean = iSumOfED / 5;  // As the window size is set to 5
       
   544     iSumOfED = 0.0;
       
   545 
       
   546     // Calculate distance from mean
       
   547     TReal dist = 0.0;
       
   548     TReal sqr = 0.0;
       
   549     TReal sum = 0.0;
       
   550     for( TInt i = 0; i < iED.Count(); i++ )
       
   551         {
       
   552         dist = iED[i] - mean;
       
   553         Math::Pow( sqr, dist, 2 );
       
   554         sum += sqr;
       
   555         }
       
   556 
       
   557     iED.Reset();
       
   558     TReal variance = sum / 5;
       
   559     iVarianceOfED.Append( variance );
       
   560     
       
   561     // Check if variance is > 5. If true then check the next set of
       
   562     // 5 variances. If there are more than two variance readings > 5
       
   563     // then compute average of the 5 readings and check if this value
       
   564     // is > 5. If true then notify movement.
       
   565     if( iVarianceOfED.Count() == 3 )
       
   566         {
       
   567         // Find average of variances
       
   568         TInt8 varianceCount = 0;
       
   569         sum = 0.0;
       
   570         for( TInt i = 0; i < iVarianceOfED.Count(); i++ )
       
   571             {
       
   572             sum += iVarianceOfED[i];
       
   573             if( iVarianceOfED[i] > 5.0 )
       
   574                 {
       
   575                 ++varianceCount;
       
   576                 }
       
   577             }
       
   578         if( varianceCount >= 2 )
       
   579             {
       
   580             iAvgOfVariance = sum / 3;   // average of 5 variance readings
       
   581             }
       
   582         else
       
   583             {
       
   584             iAvgOfVariance = 0.0;
       
   585             }
       
   586         
       
   587         iVarianceOfED.Reset();
       
   588         }
       
   589     }
       
   590     
       
   591 
       
   592 //------------------------------------------------------------
       
   593 // CLbtCellIdMvmtDet::StopNotification
       
   594 //------------------------------------------------------------
       
   595 //		
       
   596 void CLbtCellIdMvmtDet::StopNotification()
       
   597 	{
       
   598 	FUNC_ENTER("CLbtCellIdMvmtDet::StopNotification");
       
   599 	iCellIdMvmtDetGetCellData->Stop();
       
   600 	delete iPrevCellInfo;
       
   601 	iPrevCellInfo = NULL;
       
   602     delete iCurrentCellInfo;
       
   603     iCurrentCellInfo = NULL;
       
   604     delete iInitialCellInfo;
       
   605     iInitialCellInfo = NULL;
       
   606     delete iWcdmaCellInfo;
       
   607     iWcdmaCellInfo = NULL;
       
   608 	}
       
   609 
       
   610 
       
   611 //------------------------------------------------------------
       
   612 // CLbtCellIdMvmtDet::DetectShortGsmMovement
       
   613 //------------------------------------------------------------
       
   614 //
       
   615 void CLbtCellIdMvmtDet::DetectShortGsmMovement()
       
   616     {    
       
   617     LOG("=>CLbtCellIdMvmtDet::DetectShortMovement");
       
   618     // Compare BSIC and ARFCN of current reading with the intial value.
       
   619     RArray< TGsmNMR >& intialData = iInitialCellInfo->GetNMR();
       
   620     RArray< TGsmNMR >& currentData = iCurrentCellInfo->GetNMR();
       
   621     // Test
       
   622     LOG1("Initialdata count:%d",intialData.Count() );
       
   623     LOG1("Current data count:%d",currentData.Count() );
       
   624     // Test
       
   625     
       
   626     TReal ratioOfBsicVisible = ( TReal ) currentData.Count() / ( TReal ) intialData.Count();
       
   627     if( ratioOfBsicVisible < 0.5 )
       
   628         {
       
   629         LOG1("ratioOfBsicVisible:%f",ratioOfBsicVisible);
       
   630         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   631         return;
       
   632         }
       
   633     
       
   634     TReal euclidianDist = 0.0;
       
   635     TInt currentMatch = 0;
       
   636     
       
   637     for( TInt i=0;i<currentData.Count();i++ )
       
   638         for( TInt j=0;j<intialData.Count();j++ )
       
   639         {
       
   640         if( currentData[i].BSIC == intialData[j].BSIC &&
       
   641             currentData[i].ARFCN == intialData[j].ARFCN )
       
   642             {
       
   643             currentMatch++;
       
   644             euclidianDist += ( currentData[i].RxLEV - intialData[j].RxLEV )*
       
   645 	    				        ( currentData[i].RxLEV - intialData[j].RxLEV );  
       
   646 	    	}
       
   647         }
       
   648     Math::Sqrt( euclidianDist,euclidianDist );    
       
   649     
       
   650     TReal ratio = ( TReal )currentMatch / ( TReal )intialData.Count();
       
   651     
       
   652     LOG1("Euclidian distance:%f",euclidianDist);
       
   653     LOG1("ratio:%f",ratio)
       
   654     if( ratio <= 0.8 && euclidianDist >= 15 )
       
   655         {
       
   656         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement );
       
   657         LOG("Movement detected");
       
   658         }
       
   659     LOG("CLbtCellIdMvmtDet::DetectShortMovement=>");    
       
   660     }
       
   661 
       
   662 //------------------------------------------------------------
       
   663 // CLbtCellIdMvmtDet::DetectShortWcdmaMovement
       
   664 //------------------------------------------------------------
       
   665 //
       
   666 void CLbtCellIdMvmtDet::DetectShortWcdmaMovement()
       
   667     {
       
   668     FUNC_ENTER("CLbtCellIdMvmtDet::DetectShortWcdmaMovement");
       
   669     LOG("CLbtCellIdMvmtDet::DetectShortWcdmaMovement");
       
   670     // If cell change has happened, notify movement
       
   671     if( iWcdmaCellInfo->CellChangeCount() == 2 )
       
   672         {
       
   673         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement ); 
       
   674         LOG("Small cell change movement");
       
   675         return;
       
   676         }
       
   677     
       
   678     // Compare initial NMR readings with the current readings
       
   679     RArray<TWcdmaNMR>& wcdmaNMR = iWcdmaCellInfo->GetWcdmaNMR();
       
   680     
       
   681     TInt count = wcdmaNMR.Count();
       
   682     if( count == 0 )
       
   683         {
       
   684         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventDetectorFailed ); 
       
   685         return;
       
   686         }
       
   687         
       
   688     TInt cRssiDiff = Abs( wcdmaNMR[0].iCarrierRSSI - wcdmaNMR[count-1].iCarrierRSSI );
       
   689     TInt cPRscpDiff = Abs( wcdmaNMR[0].iCpichRscp - wcdmaNMR[count-1].iCpichRscp );
       
   690     TInt pathLossDiff = Abs( wcdmaNMR[0].iPathloss - wcdmaNMR[count-1].iPathloss );
       
   691     
       
   692     //Test Logs
       
   693     LOG1("cRssiDiff:%d",cRssiDiff);
       
   694     LOG1("cPRscpDiff:%d",cPRscpDiff);
       
   695     LOG1("pathLossDiff:%d",pathLossDiff);
       
   696     //Test Logs
       
   697     
       
   698     if( cRssiDiff >= 2 || ( cPRscpDiff >= 5 && pathLossDiff >= 5 ) )
       
   699         {
       
   700         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement );
       
   701         LOG("Short movement detected"); 
       
   702         }
       
   703     }
       
   704 //------------------------------------------------------------
       
   705 // CLbtCellIdMvmtDet::InitialiseL
       
   706 //------------------------------------------------------------
       
   707 //
       
   708 void CLbtCellIdMvmtDet::CheckBsicVariation()
       
   709     {
       
   710     FUNC_ENTER("CLbtCellIdMvmtDet::CheckBsicVariation");
       
   711     RArray< TGsmNMR >& intialData = iInitialCellInfo->GetNMR();
       
   712     RArray< TGsmNMR >& currentData = iPrevCellInfo->GetNMR();
       
   713     
       
   714     // Test
       
   715     LOG1("Initialdata count:%d",intialData.Count() );
       
   716     LOG1("Current data count:%d",currentData.Count() );
       
   717     // Test
       
   718     
       
   719     TInt totalMatch = 0;
       
   720     for( TInt i=0;i<currentData.Count();i++ )
       
   721         for( TInt j=0;j<intialData.Count();j++ )
       
   722         {
       
   723         if( currentData[i].BSIC == intialData[j].BSIC &&
       
   724             currentData[i].ARFCN == intialData[j].ARFCN )
       
   725             {
       
   726             totalMatch++;
       
   727             }
       
   728         }
       
   729     TReal ratio = ( TReal ) totalMatch / ( TReal ) intialData.Count();
       
   730     
       
   731     TReal comparisionFactor = CalculateComparisionFactor( iSleepDuration );
       
   732     LOG1("ratio:%f",ratio);
       
   733     LOG1("Comaparision factor:%f",comparisionFactor);
       
   734     if( ratio <= comparisionFactor )
       
   735         {
       
   736         iObserver->HandleDetectorNotification( MLbtMovementObserver::EEventMovement );
       
   737         LOG("Movement detected");
       
   738         }
       
   739     }
       
   740 
       
   741 
       
   742 //------------------------------------------------------------
       
   743 // CLbtCellIdMvmtDet::CalculateComparisionFactor
       
   744 //------------------------------------------------------------
       
   745 //
       
   746 TReal CLbtCellIdMvmtDet::CalculateComparisionFactor( TInt aSleepDuration )
       
   747     {
       
   748     if( aSleepDuration > 20 && aSleepDuration < 30 )
       
   749         {
       
   750         return 0.75;
       
   751         }
       
   752     else if( aSleepDuration > 30 && aSleepDuration < 40 )
       
   753         {
       
   754         return 0.65;
       
   755         }
       
   756     else if( aSleepDuration > 40 && aSleepDuration < 50 )
       
   757         {
       
   758         return 0.60;
       
   759         }
       
   760     else
       
   761         {
       
   762         return 0.50;
       
   763         }
       
   764     }
       
   765 
       
   766 //------------------------------------------------------------
       
   767 // CLbtCellIdMvmtDet::InitialiseL
       
   768 //------------------------------------------------------------
       
   769 //
       
   770 void CLbtCellIdMvmtDet::InitializeL()
       
   771     {
       
   772     FUNC_ENTER("CLbtCellIdMvmtDet::InitializeL");
       
   773     CCommsDatabase* const db = CCommsDatabase::NewL( ETrue );
       
   774     CleanupStack::PushL( db ); 
       
   775 
       
   776     TUint32 modemId = 0; 
       
   777     db->GetGlobalSettingL( TPtrC( MODEM_PHONE_SERVICES_SMS ), modemId ); 
       
   778     CCommsDbTableView* const view =
       
   779         db->OpenViewMatchingUintLC( TPtrC( MODEM ), TPtrC( COMMDB_ID ), modemId ); 
       
   780 
       
   781     TInt err = view->GotoFirstRecord();
       
   782     if( err != KErrNone )
       
   783         {
       
   784         User::Leave( err );
       
   785         }
       
   786 
       
   787     HBufC* nameBuf = NULL;
       
   788     nameBuf = view->ReadLongTextLC( TPtrC( MODEM_TSY_NAME ) );
       
   789 
       
   790     User::LeaveIfError( iTelServer.Connect() );
       
   791     err = iTelServer.LoadPhoneModule( *nameBuf );
       
   792     if( err != KErrNone )
       
   793         {
       
   794         User::Leave( err );
       
   795         }
       
   796 
       
   797     // For the phone information
       
   798     RTelServer::TPhoneInfo info;
       
   799     iTelServer.GetPhoneInfo( 0, info ); 
       
   800     err = iMPhone.Open( iTelServer, info.iName );
       
   801     if( err != KErrNone )
       
   802         {
       
   803         User::Leave( err );
       
   804         }
       
   805 
       
   806     // initialise etel multimode custom api
       
   807     err = iCApi.Open( iMPhone );
       
   808     if( err != KErrNone )
       
   809         {
       
   810         User::Leave( err );
       
   811         }
       
   812 
       
   813     CleanupStack::PopAndDestroy( 3 ); // nameBuf, view and db    
       
   814     }