|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // locationrequesthandler.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 |
|
19 #include "lbscommoninternaldatatypes.h" |
|
20 #include "lbslocationrequesthandler.h" |
|
21 #include "lbslocsourcegps.h" |
|
22 #include "lbsdevloggermacros.h" |
|
23 #include <lbs/lbslocerrors.h> |
|
24 |
|
25 CLocationRequestHandler * CLocationRequestHandler::NewL |
|
26 ( |
|
27 MLocationRequestHandlerObserver& aObserver, |
|
28 const RLbsPositionUpdateRequests::TChannelIdentifer& aChannel |
|
29 ) |
|
30 { |
|
31 LBSLOG(ELogP1, "CLocationRequestHandler::NewL()\n"); |
|
32 CLocationRequestHandler * self = new(ELeave) CLocationRequestHandler (aObserver, aChannel); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(aChannel); |
|
35 CleanupStack::Pop(); |
|
36 return self; |
|
37 } |
|
38 |
|
39 CLocationRequestHandler::CLocationRequestHandler(MLocationRequestHandlerObserver& aObserver, const RLbsPositionUpdateRequests::TChannelIdentifer& aChannel) : |
|
40 CActive(CActive::EPriorityStandard), |
|
41 iObserver(aObserver), |
|
42 iChannel(aChannel), |
|
43 iRequestState(EIdle) |
|
44 { |
|
45 LBSLOG(ELogP1, "CLocationRequestHandler::CLocationRequestHandler()\n"); |
|
46 } |
|
47 |
|
48 void CLocationRequestHandler::ConstructL(const RLbsPositionUpdateRequests::TChannelIdentifer& aChannel) |
|
49 { |
|
50 LBSLOG(ELogP1, "CLocationRequestHandler::ConstructL()\n"); |
|
51 CActiveScheduler::Add(this); |
|
52 iposUpdateReq.OpenL(aChannel); |
|
53 iTimer = CLbsCallbackTimer::NewL(*this); |
|
54 |
|
55 iposUpdateReq.NotifyPositionUpdateRequestChange(iStatus); |
|
56 SetActive(); |
|
57 } |
|
58 |
|
59 CLocationRequestHandler::~CLocationRequestHandler() |
|
60 { |
|
61 LBSLOG(ELogP1, "CLocationRequestHandler::~CLocationRequestHandler()\n"); |
|
62 Cancel(); |
|
63 iposUpdateReq.Close(); |
|
64 delete iTimer; |
|
65 } |
|
66 |
|
67 void CLocationRequestHandler::ActivateRequest() |
|
68 { |
|
69 TLbsLocRequestQualityInt fred; |
|
70 |
|
71 LBSLOG(ELogP1, "CLocationRequestHandler::ActivateRequest()\n"); |
|
72 // Invalidate if any |
|
73 InvalidateRequest(); |
|
74 |
|
75 TTime timeNow; |
|
76 TTime endTime; |
|
77 timeNow.UniversalTime(); |
|
78 iRequestActivationTime = timeNow; |
|
79 |
|
80 // TT=0 means immediate request |
|
81 endTime = iRequest.TargetTime() != 0 ? iRequest.TargetTime() : timeNow; |
|
82 endTime = LbsTimerUtils::AddUpInt64TimersWithOverflowCheck(endTime,iRequest.RequestQuality().MaxFixTime()); |
|
83 |
|
84 if (endTime > timeNow) // if it end in the future |
|
85 { |
|
86 iTimer->EventAtUTC(endTime, 0); |
|
87 iRequestState = EActive; |
|
88 } |
|
89 } |
|
90 |
|
91 void CLocationRequestHandler::InvalidateRequest() |
|
92 { |
|
93 LBSLOG(ELogP1, "CLocationRequestHandler::InvalidateRequest()\n"); |
|
94 iRequestState = EIdle; |
|
95 iTimer->Cancel(); |
|
96 } |
|
97 |
|
98 TBool CLocationRequestHandler::IsRequestActive() const |
|
99 { |
|
100 LBSLOG(ELogP1, "CLocationRequestHandler::IsRequestActive()\n"); |
|
101 return iRequestState == EActive || iRequestState == EActiveRestartOnTargetTime; |
|
102 } |
|
103 |
|
104 TTime CLocationRequestHandler::GetStartTime() const |
|
105 { |
|
106 LBSLOG(ELogP1, "CLocationRequestHandler::GetStartTime()\n"); |
|
107 return (iRequest.TargetTime()); |
|
108 }; |
|
109 |
|
110 TTime CLocationRequestHandler::GetTimeActivated() const |
|
111 { |
|
112 // Returns the time the request was actually activated |
|
113 // Needed when calculating max fix time for combined requests |
|
114 // when TargetTime is zero (i.e. immediate requests) |
|
115 LBSLOG(ELogP1, "CLocationRequestHandler::GetTimeActivated()\n"); |
|
116 return iRequestActivationTime; |
|
117 }; |
|
118 |
|
119 TLbsLocRequestQualityInt CLocationRequestHandler::GetQuality() const |
|
120 { |
|
121 LBSLOG(ELogP1, "CLocationRequestHandler::GetQuality()\n"); |
|
122 |
|
123 return iRequest.RequestQuality(); |
|
124 }; |
|
125 |
|
126 TBool CLocationRequestHandler::GetNewClient() const |
|
127 { |
|
128 LBSLOG(ELogP1, "CLocationRequestHandler::GetNewClient()\n"); |
|
129 return iRequest.NewClient(); |
|
130 }; |
|
131 |
|
132 void CLocationRequestHandler::DoCancel() |
|
133 { |
|
134 LBSLOG(ELogP1, "CLocationRequestHandler::DoCancel()\n"); |
|
135 iposUpdateReq.CancelNotifyPositionUpdateRequestChange(); |
|
136 iTimer->Cancel(); |
|
137 } |
|
138 |
|
139 //------------------------------------------------------------------------------------------------------------ |
|
140 void CLocationRequestHandler::RunL() |
|
141 { |
|
142 LBSLOG2(ELogP1, "CLocationRequestHandler::RunL() Begin. Status: %d\n", iStatus.Int()); |
|
143 __ASSERT_DEBUG(iStatus.Int() == KErrNone, User::Panic(KLbsAGPSManFault, iStatus.Int())); |
|
144 |
|
145 iposUpdateReq.NotifyPositionUpdateRequestChange(iStatus); |
|
146 SetActive(); |
|
147 |
|
148 ProcessAnyOutstandingRequestL(); |
|
149 LBSLOG(ELogP1, "CLocationRequestHandler::RunL() End\n"); |
|
150 } |
|
151 |
|
152 /* When ran the first time (after AGPS Manager startup) the last known |
|
153 system status is passed to the NG */ |
|
154 void CLocationRequestHandler::ProcessAnyOutstandingRequestL() |
|
155 { |
|
156 LBSLOG(ELogP1, "CLocationRequestHandler::ProcessAnyOutstandingRequestL() Begin\n"); |
|
157 |
|
158 TLbsPositionUpdateRequestBase updateRequest; |
|
159 User::LeaveIfError(iposUpdateReq.GetPositionUpdateRequest(updateRequest)); |
|
160 |
|
161 TLbsPositionUpdateRequest* request = (reinterpret_cast<TLbsPositionUpdateRequest*>(&updateRequest)); |
|
162 |
|
163 // Process the requst |
|
164 switch(updateRequest.Type()) |
|
165 { |
|
166 case TLbsPositionUpdateRequestBase::ECancel: |
|
167 LBSLOG(ELogP2, "Location Cancel received from LS or NRH.\n"); |
|
168 ProcessSystemStatusAdvice(updateRequest); |
|
169 |
|
170 if(!iLastRequestWasCancel) |
|
171 { |
|
172 InvalidateRequest(); |
|
173 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonCancel); |
|
174 iLastRequestWasCancel = ETrue; |
|
175 } |
|
176 break; |
|
177 |
|
178 case TLbsPositionUpdateRequestBase::EUpdateRequest: |
|
179 LBSLOG(ELogP2, "Location Request received from LS or NRH.\n"); |
|
180 LBSLOG5(ELogP2, " TargetTime: %d:%d:%d.%d", request->TargetTime().DateTime().Hour(), |
|
181 request->TargetTime().DateTime().Minute(), |
|
182 request->TargetTime().DateTime().Second(), |
|
183 request->TargetTime().DateTime().MicroSecond()); |
|
184 LBSLOG2(ELogP2, " Max Fix Time: %ld", request->RequestQuality().MaxFixTime().Int64()); |
|
185 LBSLOG3(ELogP2, " Accuracy H/V: %f/%f", request->RequestQuality().MinHorizontalAccuracy(), |
|
186 request->RequestQuality().MinVerticalAccuracy()); |
|
187 |
|
188 iLastRequestWasCancel = EFalse; |
|
189 ProcessSystemStatusAdvice(updateRequest); |
|
190 |
|
191 iRequest = *request; |
|
192 ActivateRequest(); |
|
193 if (iRequestState == EActive) |
|
194 { |
|
195 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonRequest); // call back to MainLogic |
|
196 } |
|
197 break; |
|
198 |
|
199 case TLbsPositionUpdateRequestBase::EStatus: |
|
200 LBSLOG(ELogP2, "Status received from LS or NRH.\n"); |
|
201 iLastRequestWasCancel = EFalse; |
|
202 ProcessSystemStatusAdvice(updateRequest); |
|
203 break; |
|
204 |
|
205 default: |
|
206 { |
|
207 LBSLOG_WARN2(ELogP2, "Unknown update request type: %d \n", updateRequest.Type()); |
|
208 iLastRequestWasCancel = EFalse; |
|
209 break; |
|
210 } |
|
211 } |
|
212 LBSLOG(ELogP1, "CLocationRequestHandler::ProcessAnyOutstandingRequestL() End\n"); |
|
213 } |
|
214 |
|
215 /** */ |
|
216 void CLocationRequestHandler::ProcessSystemStatusAdvice(TLbsPositionUpdateRequestBase& aRequest) |
|
217 { |
|
218 LBSLOG(ELogP1, "CLocationRequestHandler::ProcessSystemStatusAdvice()\n"); |
|
219 TLbsPositionUpdateRequestStatus* status; |
|
220 status = reinterpret_cast<TLbsPositionUpdateRequestStatus*>(&aRequest); |
|
221 ProcessPowerModeAdvice(status->PowerAdvice()); |
|
222 iObserver.OnSystemStatusAdvice(iChannel, status->Tracking()); |
|
223 } |
|
224 |
|
225 void CLocationRequestHandler::ProcessPowerModeAdvice(TLbsPositionUpdateRequestBase::TPowerAdvice aMode) |
|
226 { |
|
227 LBSLOG(ELogP1, "CLocationRequestHandler::ProcessPowerModeAdvice()\n"); |
|
228 if (TLbsPositionUpdateRequestBase::ENoPowerAdvice != aMode) |
|
229 { |
|
230 CLbsLocationSourceGpsBase::TPowerMode powerMode; |
|
231 switch (aMode) |
|
232 { |
|
233 //Identify the power advice being sent |
|
234 case TLbsPositionUpdateRequestBase::EPowerAdviceOn: |
|
235 { |
|
236 powerMode = CLbsLocationSourceGpsBase::EPowerModeOn; |
|
237 break; |
|
238 } |
|
239 case TLbsPositionUpdateRequestBase::EPowerAdviceStandby: |
|
240 { |
|
241 powerMode = CLbsLocationSourceGpsBase::EPowerModeStandby; |
|
242 break; |
|
243 } |
|
244 case TLbsPositionUpdateRequestBase::EPowerAdviceOff: |
|
245 { |
|
246 powerMode = CLbsLocationSourceGpsBase::EPowerModeOff; |
|
247 break; |
|
248 } |
|
249 case TLbsPositionUpdateRequestBase::EPowerAdviceClosed: |
|
250 { |
|
251 powerMode = CLbsLocationSourceGpsBase::EPowerModeClose; |
|
252 break; |
|
253 } |
|
254 default: |
|
255 { |
|
256 LBSLOG_WARN2(ELogP2, "Unknown power mode: %d \n", aMode); |
|
257 break; |
|
258 } |
|
259 } |
|
260 |
|
261 iObserver.OnPowerModeAdvice(iChannel, powerMode); |
|
262 } |
|
263 } |
|
264 |
|
265 TBool CLocationRequestHandler::IsAccuracyRequirementMet(TReal32 aHorizontalAccuracy, TReal32 /*aVerticalAccuracy*/) |
|
266 { |
|
267 LBSLOG(ELogP1, "CLocationRequestHandler::ProcessLocationUpdate()\n"); |
|
268 TBool rc = EFalse; |
|
269 if (EIdle != iRequestState) |
|
270 { |
|
271 TLbsLocRequestQualityInt quality = GetQuality(); |
|
272 |
|
273 TTimeIntervalMicroSeconds mft = quality.MaxFixTime(); |
|
274 |
|
275 TTime targ = iRequest.TargetTime(); |
|
276 if (targ == TTime(0)) |
|
277 { |
|
278 targ.UniversalTime(); |
|
279 } |
|
280 TTime endtarg = LbsTimerUtils::AddUpInt64TimersWithOverflowCheck(targ,mft); |
|
281 |
|
282 TTime now; |
|
283 now.UniversalTime(); |
|
284 |
|
285 if ((now >= targ) && (now <= endtarg) && |
|
286 (aHorizontalAccuracy <= quality.MinHorizontalAccuracy())) |
|
287 { |
|
288 LBSLOG(ELogP2, "Time window ok. Quality meet. Invalidating request.\n"); |
|
289 InvalidateRequest(); |
|
290 rc = ETrue; |
|
291 } |
|
292 } |
|
293 |
|
294 return rc; |
|
295 } |
|
296 |
|
297 void CLocationRequestHandler::CompleteSelf(TInt aReason) |
|
298 { |
|
299 LBSLOG(ELogP1, "CLocationRequestHandler::CompleteSelf()\n"); |
|
300 TRequestStatus* pStat = &iStatus; |
|
301 User::RequestComplete(pStat, aReason); |
|
302 SetActive(); |
|
303 } |
|
304 |
|
305 |
|
306 void CLocationRequestHandler::OnTimerEventL(TInt /*aTimerId*/) |
|
307 { |
|
308 LBSLOG(ELogP1, "CLocationRequestHandler::OnTimerEventL()\n"); |
|
309 |
|
310 //Need to return to EActive state |
|
311 if(iRequestState == EActiveRestartOnTargetTime) |
|
312 { |
|
313 LBSLOG(ELogP2, "Start time occured for the LS request. Reactivate request.\n"); |
|
314 InvalidateRequest(); |
|
315 |
|
316 TTime timeNow; |
|
317 timeNow.UniversalTime(); |
|
318 |
|
319 // TT=0 means immediate request |
|
320 TTime endTime = iRequest.TargetTime() != 0 ? iRequest.TargetTime() : iRequestActivationTime; |
|
321 endTime = LbsTimerUtils::AddUpInt64TimersWithOverflowCheck(endTime,iRequest.RequestQuality().MaxFixTime()); |
|
322 |
|
323 if (endTime > timeNow) // if it end in the future |
|
324 { |
|
325 iTimer->EventAtUTC(endTime, 0); |
|
326 iRequestState = EActive; |
|
327 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonRequest); |
|
328 } |
|
329 else |
|
330 { |
|
331 LBSLOG(ELogP2, "LS or NRH request timed out.\n"); |
|
332 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonTimeout); |
|
333 } |
|
334 } |
|
335 else |
|
336 { |
|
337 LBSLOG(ELogP2, "LS or NRH request timed out.\n"); |
|
338 InvalidateRequest(); |
|
339 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonTimeout); |
|
340 } |
|
341 } |
|
342 |
|
343 TInt CLocationRequestHandler::RunError(TInt aError) |
|
344 { |
|
345 LBSLOG(ELogP1, "CLocationRequestHandler::RunError() Begin\n"); |
|
346 // handle RunL leaving - in our case we do nothing |
|
347 // as this means we have had encountered a program inconsistency |
|
348 // By doing nothing here causes the main manager thread to exit |
|
349 // and the Lbs root process resolves any issues - by stopping and restarting |
|
350 // lbs components |
|
351 LBSLOG_ERR2(ELogP2, " %d \n", aError); |
|
352 |
|
353 LBSLOG(ELogP1, "CLocationRequestHandler::RunError() End\n"); |
|
354 return aError; |
|
355 } |
|
356 |
|
357 TInt CLocationRequestHandler::OnTimerError(TInt /*aTimerId*/, TInt aError) |
|
358 { |
|
359 LBSLOG(ELogP1, "CLocationRequestHandler::OnTimerError() Begin\n"); |
|
360 // handle the same way as CLocationRequestHandler::RunError |
|
361 LBSLOG_ERR2(ELogP2, " %d \n", aError); |
|
362 LBSLOG(ELogP1, "CLocationRequestHandler::OnTimerError() End\n"); |
|
363 return aError; |
|
364 } |
|
365 |
|
366 TBool CLocationRequestHandler::GpsTimingOfCellFramesRequested() const |
|
367 { |
|
368 LBSLOG(ELogP1, "CLocationRequestHandler::GpsTimingOfCellFramesRequested()\n"); |
|
369 return iRequest.RequestMethod().GpsTimingOfCellFramesRequested(); |
|
370 } |
|
371 |
|
372 |
|
373 TPositionModuleInfo::TTechnologyType CLocationRequestHandler::GetTechnologyTypeFromRequest(TInt aIndex) const |
|
374 { |
|
375 LBSLOG(ELogP1, "CLocationRequestHandler::GetTechnologyTypeFromRequest() Begin\n"); |
|
376 TLbsNetPosMethodInt posMethod; |
|
377 TInt result = iRequest.RequestMethod().GetPosMethod(aIndex, posMethod); |
|
378 if (result == KErrNone) |
|
379 { |
|
380 return posMethod.PosMode(); |
|
381 } |
|
382 LBSLOG(ELogP1, "CLocationRequestHandler::GetTechnologyTypeFromRequest() End\n"); |
|
383 return TPositionModuleInfo::ETechnologyUnknown; |
|
384 } |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 void CLocationRequestHandler::RestartOnTargetTime() |
|
390 { |
|
391 LBSLOG(ELogP1, "CLocationRequestHandler::RestartOnTargetTime() Begin\n"); |
|
392 if(iRequestState == EIdle) |
|
393 { |
|
394 __ASSERT_DEBUG(0, User::Invariant()); |
|
395 LBSLOG(ELogP1, "CLocationRequestHandler::RestartOnTargetTime() End\n"); |
|
396 return; |
|
397 } |
|
398 |
|
399 InvalidateRequest(); |
|
400 |
|
401 TTime timeNow; |
|
402 timeNow.UniversalTime(); |
|
403 |
|
404 TTime startTime = iRequest.TargetTime()==0 ? iRequestActivationTime : iRequest.TargetTime(); |
|
405 //Even though it starts in the past, it is ok - it will be restarted immediately. |
|
406 iTimer->EventAtUTC(startTime, 0); |
|
407 iRequestState = EActiveRestartOnTargetTime; |
|
408 |
|
409 LBSLOG(ELogP1, "CLocationRequestHandler::RestartOnTargetTime() End\n"); |
|
410 } |
|
411 |
|
412 |
|
413 void CLocationRequestHandler::CancelRestartOnTargetTime() |
|
414 { |
|
415 LBSLOG(ELogP1, "CLocationRequestHandler::CancelRestartOnTargetTime() Begin\n"); |
|
416 if(iRequestState == EActiveRestartOnTargetTime) |
|
417 { |
|
418 InvalidateRequest(); |
|
419 |
|
420 TTime timeNow; |
|
421 timeNow.UniversalTime(); |
|
422 |
|
423 // TT=0 means immediate request |
|
424 TTime endTime = iRequest.TargetTime() != 0 ? iRequest.TargetTime() : iRequestActivationTime; |
|
425 endTime = LbsTimerUtils::AddUpInt64TimersWithOverflowCheck(endTime,iRequest.RequestQuality().MaxFixTime()); |
|
426 |
|
427 if(endTime > timeNow) // if it end in the future |
|
428 { |
|
429 iTimer->EventAtUTC(endTime, 0); |
|
430 iRequestState = EActive; |
|
431 } |
|
432 else |
|
433 { |
|
434 LBSLOG(ELogP2, "LS or NRH request timed out.\n"); |
|
435 iObserver.OnLocationRequestStateChanged(iChannel, MLocationRequestHandlerObserver::EReasonTimeout); |
|
436 } |
|
437 } |
|
438 LBSLOG(ELogP1, "CLocationRequestHandler::CancelRestartOnTargetTime() End\n"); |
|
439 } |