|
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 } |