|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalTechnology |
|
19 @released |
|
20 */ |
|
21 |
|
22 #include "lbsdevloggermacros.h" |
|
23 #include "agpsinterfacehandler.h" |
|
24 #include "nrhpanic.h" |
|
25 #include "lbsnetregstatusint.h" |
|
26 |
|
27 |
|
28 // Pre-defined technology types for common positioning modes. |
|
29 const TPositionModuleInfo::TTechnologyType KTerminalAssistedMode = |
|
30 (TPositionModuleInfo::ETechnologyNetwork | |
|
31 TPositionModuleInfo::ETechnologyAssisted); |
|
32 const TPositionModuleInfo::TTechnologyType KTerminalBasedMode = |
|
33 (TPositionModuleInfo::ETechnologyTerminal | |
|
34 TPositionModuleInfo::ETechnologyAssisted); |
|
35 const TPositionModuleInfo::TTechnologyType KAutonomousMode = |
|
36 (TPositionModuleInfo::ETechnologyTerminal); |
|
37 |
|
38 /** Constructor. |
|
39 */ |
|
40 CAgpsInterfaceHandler::CAgpsInterfaceHandler( |
|
41 MAgpsInterfaceHandlerObserver& aObserver, |
|
42 CLbsAdmin& aAdmin, |
|
43 RLbsNetworkRegistrationStatus& aNetRegStatus) : |
|
44 iObserver(aObserver), |
|
45 iAdmin(aAdmin), |
|
46 iNetRegStatus(aNetRegStatus), |
|
47 iX3pStatus(EX3pStatusIdle), |
|
48 iCombinedPowerModeAdvice(TLbsPositionUpdateRequestBase::EPowerAdviceOff), |
|
49 iCombinedRequestGpsMode(EGpsRequestModeUnknown) |
|
50 { |
|
51 } |
|
52 |
|
53 /** Destructor. |
|
54 */ |
|
55 CAgpsInterfaceHandler::~CAgpsInterfaceHandler() |
|
56 { |
|
57 iRequests.Close(); |
|
58 delete iMeasurementUpdateMonitor; |
|
59 delete iLocationUpdateMonitor; |
|
60 } |
|
61 |
|
62 /** |
|
63 */ |
|
64 CAgpsInterfaceHandler* CAgpsInterfaceHandler::NewL( |
|
65 MAgpsInterfaceHandlerObserver& aObserver, |
|
66 CLbsAdmin& aAdmin, |
|
67 RLbsNetworkRegistrationStatus& aNetRegStatus) |
|
68 { |
|
69 CAgpsInterfaceHandler* self = new (ELeave) CAgpsInterfaceHandler(aObserver, aAdmin, aNetRegStatus); |
|
70 CleanupStack::PushL(self); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop(self); |
|
73 return self; |
|
74 } |
|
75 |
|
76 /** |
|
77 */ |
|
78 |
|
79 const TInt KLbsDefaultMaxNumLocationRequests = 4; |
|
80 |
|
81 void CAgpsInterfaceHandler::ConstructL() |
|
82 { |
|
83 iLocationUpdateMonitor = CLbsLocUpdateMonitor::NewL(*this); |
|
84 iMeasurementUpdateMonitor = CLbsMeasurementInfoMonitor::NewL(*this); |
|
85 |
|
86 TInt err = iAdmin.Get(KLbsSettingMaximumExternalLocateRequests, iMaxNumLocationRequests); |
|
87 if (err != KErrNone) |
|
88 { |
|
89 iMaxNumLocationRequests = KLbsDefaultMaxNumLocationRequests; |
|
90 } |
|
91 |
|
92 iRequests.ReserveL(iMaxNumLocationRequests+1); // +1 for processing emergencies |
|
93 |
|
94 // Get the A-GPS device mode capabilities: |
|
95 err = LbsModuleInfo::GetDeviceCapabilities(KLbsGpsLocManagerUid, iDeviceGpsModeCaps); |
|
96 if(err != KErrNone || (iDeviceGpsModeCaps==TPositionModuleInfoExtended::EDeviceGpsModeNone)) |
|
97 { |
|
98 // Assume module supports hybrid if it has not reported its capabilities in module info file |
|
99 iDeviceGpsModeCaps = TPositionModuleInfoExtended::EDeviceGpsModeSimultaneousTATB; |
|
100 } |
|
101 |
|
102 |
|
103 } |
|
104 |
|
105 /** Called to initialise a location request. |
|
106 |
|
107 This is used to tell the AGPS Interface that a GPS location request |
|
108 is goind to happen 'soon'. Usually, this means we should update the |
|
109 power mode advice to at least 'standby', to give the GPS hardware |
|
110 as much time as possible to warm up. |
|
111 |
|
112 @param aSessionId Session Id of the request that is started. |
|
113 |
|
114 @return KErrNone if no problems, or one of the standard Symbian |
|
115 error codes if there was a problem storing the new request. |
|
116 */ |
|
117 TInt CAgpsInterfaceHandler::PreStartPositioning( |
|
118 const TLbsNetSessionIdInt& aSessionId, TBool aEmergency) |
|
119 { |
|
120 // Add the request to the array |
|
121 TAgpsRequest newRequest; |
|
122 newRequest.iSessionId = &aSessionId; |
|
123 newRequest.iState = EAgpsRequestStateIdle; |
|
124 |
|
125 TInt err = AddOrUpdateRequest(newRequest, aEmergency); |
|
126 |
|
127 if (err != KErrNone) |
|
128 { |
|
129 return err; |
|
130 } |
|
131 |
|
132 // Update the GPS power mode advice to the AGPS Manager |
|
133 TLbsPositionUpdateRequestBase::TPowerAdvice newPowerAdvice; |
|
134 CalculateCombinedPowerModeAdvice(newPowerAdvice); |
|
135 if (newPowerAdvice != iCombinedPowerModeAdvice) |
|
136 { |
|
137 iCombinedPowerModeAdvice = newPowerAdvice; |
|
138 iLocationUpdateMonitor->SendPowerAdviceRequest(iCombinedPowerModeAdvice); |
|
139 } |
|
140 |
|
141 return err; |
|
142 } |
|
143 |
|
144 /** Called to start a location request. |
|
145 |
|
146 This is used when the CLbsPrivLocFsm actually wants to send |
|
147 a location request to the AGPS Manager. |
|
148 |
|
149 This function must combine the new request with any existing |
|
150 request(s) - this includes quality params and GPS mode, before |
|
151 sending a request to the AGPS Manager. |
|
152 |
|
153 @param aSessionId Session Id of the request that is started. |
|
154 @param aMethod GPS mode(s) to use, as set by the network. |
|
155 @param aQuality quality params to use, as set by the network. |
|
156 |
|
157 @return KErrNone if no problems, or one of the standard Symbian |
|
158 error codes if there was a problem storing the new request. |
|
159 */ |
|
160 TInt CAgpsInterfaceHandler::StartPositioning( |
|
161 const TLbsNetSessionIdInt& aSessionId, |
|
162 const TLbsNetPosRequestMethodInt& aMethod, |
|
163 const TLbsNetPosRequestQualityInt& aQuality, |
|
164 TBool aEmergency) |
|
165 { |
|
166 // Check that the new request GPS mode is valid |
|
167 TGpsRequestMode newRequestGpsMode = ConvertPosMethodToGpsRequestMode(aMethod); |
|
168 TGpsRequestMode newCombinedGpsMode; |
|
169 TInt err = CalculateNewCombinedRequestMethod( |
|
170 iCombinedRequestGpsMode, |
|
171 newRequestGpsMode, |
|
172 newCombinedGpsMode, |
|
173 aEmergency); |
|
174 if (err != KErrNone) |
|
175 { |
|
176 RemoveRequest(aSessionId); |
|
177 return err; |
|
178 } |
|
179 |
|
180 // Add (or update) the request to the buffer |
|
181 TAgpsRequest newRequest; |
|
182 newRequest.iSessionId = &aSessionId; |
|
183 newRequest.iState = EAgpsRequestStateActive; |
|
184 newRequest.iGpsMode = newRequestGpsMode; |
|
185 newRequest.iPosQuality = &aQuality; |
|
186 TTime now; |
|
187 now.UniversalTime(); |
|
188 newRequest.iEndTime = (now + aQuality.MaxFixTime()); |
|
189 newRequest.iGpsTimingOfCellFramesRequested = aMethod.GpsTimingOfCellFramesRequested(); |
|
190 err = AddOrUpdateRequest(newRequest, aEmergency); |
|
191 if (err != KErrNone) |
|
192 { |
|
193 return err; |
|
194 } |
|
195 |
|
196 // Use the new combined GPS mode |
|
197 iCombinedRequestGpsMode = newCombinedGpsMode; |
|
198 |
|
199 // Combine Quality. |
|
200 CalculateCombinedRequestQuality(); |
|
201 |
|
202 // Send the new combined request to the AGPS manager. |
|
203 SendCombinedLocationRequest(); |
|
204 |
|
205 return err; |
|
206 } |
|
207 |
|
208 /** Temporarily stop an existing location request. |
|
209 |
|
210 This function is used when a location request has finished, |
|
211 but the session it belongs to hasn't finished yet. For example, |
|
212 in terminal assisted or hybrid mode, there is more than one location |
|
213 request within a session, so the it should not be removed from the |
|
214 list until it has completely finished. |
|
215 */ |
|
216 void CAgpsInterfaceHandler::HoldPositioning( |
|
217 const TLbsNetSessionIdInt& aSessionId, |
|
218 TInt /*aReason*/) |
|
219 { |
|
220 // Find a matching request. |
|
221 TInt index = iRequests.Find(aSessionId, IsSessionIdEqual); |
|
222 if (index == KErrNotFound) |
|
223 { |
|
224 // If can't find one, just ignore it (but LBSLOG_ERR)? |
|
225 LBSLOG_ERR2(ELogP3, "Failed to find a match for sessionId %d.", aSessionId.SessionNum()); |
|
226 return; |
|
227 } |
|
228 |
|
229 // Set the request to 'hold'. |
|
230 iRequests[index].iState = EAgpsRequestStateHold; |
|
231 } |
|
232 |
|
233 /** Stop and remove a location request. |
|
234 |
|
235 This function is used when a session has finished, and |
|
236 the location request can be removed from the list. |
|
237 */ |
|
238 void CAgpsInterfaceHandler::StopPositioning( |
|
239 const TLbsNetSessionIdInt& aSessionId) |
|
240 { |
|
241 // Remove request from iRequests. |
|
242 RemoveRequest(aSessionId); |
|
243 |
|
244 if (IsAnyRequestState(EAgpsRequestStateActive)) |
|
245 { |
|
246 // If there are any other active requests, combine them and send |
|
247 // a new location request. |
|
248 |
|
249 // Combine quality |
|
250 CalculateCombinedRequestQuality(); |
|
251 |
|
252 // Send the new combined request to the AGPS manager. |
|
253 SendCombinedLocationRequest(); |
|
254 } |
|
255 else if (!IsAnyRequestState(EAgpsRequestStateHold) |
|
256 && iLocationRequestActive) |
|
257 { |
|
258 // There are no requests that are either active or on hold, so send |
|
259 // a cancel message to the AGPS manager. |
|
260 CalculateCombinedPowerModeAdvice(iCombinedPowerModeAdvice); |
|
261 iLocationUpdateMonitor->SendCancelRequest(iCombinedPowerModeAdvice); |
|
262 iLocationRequestActive = EFalse; |
|
263 |
|
264 // Also reset the combined request parameters |
|
265 iCombinedRequestGpsMode = EGpsRequestModeUnknown; |
|
266 } |
|
267 else |
|
268 { |
|
269 // Update the GPS power mode advice to the AGPS Manager |
|
270 TLbsPositionUpdateRequestBase::TPowerAdvice newPowerAdvice; |
|
271 CalculateCombinedPowerModeAdvice(newPowerAdvice); |
|
272 if (newPowerAdvice != iCombinedPowerModeAdvice) |
|
273 { |
|
274 iCombinedPowerModeAdvice = newPowerAdvice; |
|
275 iLocationUpdateMonitor->SendPowerAdviceRequest(iCombinedPowerModeAdvice); |
|
276 } |
|
277 } |
|
278 } |
|
279 |
|
280 /** Check that it is ok to send the position update to state machine(s). |
|
281 |
|
282 Some position updates should be ignored by the NRH, these are: |
|
283 1) Conflict control updates (aConflictControl = ETrue), only the |
|
284 LocServer is interested in these. |
|
285 2) In hybrid, if the params are 'invalid'. Some licensees use special |
|
286 values in the position update to flag that it should not be used, |
|
287 e.g. if the horizontal accuracy is 0. |
|
288 */ |
|
289 TBool CAgpsInterfaceHandler::CheckPositionUpdateIsValid( |
|
290 TBool aConflictControl, |
|
291 TInt aReason, |
|
292 const TPositionExtendedSatelliteInfo& aPosInfo, |
|
293 const TTime& /*aActualTime*/) |
|
294 { |
|
295 // Some updates are only meant for the LocServer - they |
|
296 // have aConflictControl == ETrue. We shouldn't send these |
|
297 // to the PrivLocHandler. |
|
298 if (aConflictControl) |
|
299 { |
|
300 return EFalse; |
|
301 } |
|
302 |
|
303 // For hybrid position, first check whether the data is valid. If any of |
|
304 // longitude, latitude, or horizontal accuracy is missing, or horizontal |
|
305 // accuracy is zero, then it's not valid, so there's no point going any |
|
306 // further. |
|
307 if ((iCombinedRequestGpsMode == EGpsRequestModeHybrid) && (aReason == KErrNone)) |
|
308 { |
|
309 TPosition pos; |
|
310 aPosInfo.GetPosition(pos); |
|
311 if (Math::IsNaN(pos.Latitude()) || |
|
312 Math::IsNaN(pos.Longitude()) || |
|
313 Math::IsNaN(pos.HorizontalAccuracy()) || |
|
314 (pos.HorizontalAccuracy() == 0)) |
|
315 { |
|
316 return EFalse; |
|
317 } |
|
318 } |
|
319 |
|
320 return ETrue; |
|
321 } |
|
322 |
|
323 /** Get the latest update value from the GPS position bus. |
|
324 |
|
325 Note: Some updates are intended only for the LocServer, these |
|
326 all have conflictControl == ETrue, so in this case we return |
|
327 KErrNotFound to tell the caller it shouldn't be used. |
|
328 |
|
329 @param aReason Reason code for the update. Set by the AGPS manager. |
|
330 @param aPosInfo Position data for the update. |
|
331 @param aTimeStamp Time the update arrived in the LBS system. |
|
332 |
|
333 @return KErrNone usually, but KErrNotFound if the update is invalid. |
|
334 */ |
|
335 TInt CAgpsInterfaceHandler::GetPosition( |
|
336 TInt& aReason, |
|
337 TPositionExtendedSatelliteInfo& aPosInfo, |
|
338 TTime& aTimeStamp) |
|
339 { |
|
340 TBool conflictControl; |
|
341 iLocationUpdateMonitor->GetPosition( |
|
342 conflictControl, |
|
343 aReason, |
|
344 aPosInfo, |
|
345 aTimeStamp); |
|
346 |
|
347 if (CheckPositionUpdateIsValid(conflictControl, |
|
348 aReason, |
|
349 aPosInfo, |
|
350 aTimeStamp)) |
|
351 { |
|
352 return KErrNone; |
|
353 } |
|
354 else |
|
355 { |
|
356 return KErrNotFound; |
|
357 } |
|
358 } |
|
359 |
|
360 /** Get the latest update from the GPS measurement results bus. |
|
361 */ |
|
362 void CAgpsInterfaceHandler::GetMeasurement( |
|
363 TInt& aReason, |
|
364 TPositionGpsMeasurementInfo& aPosInfo, |
|
365 TTime& aTimeStamp) |
|
366 { |
|
367 iMeasurementUpdateMonitor->GetMeasurement(aReason, aPosInfo, aTimeStamp); |
|
368 } |
|
369 |
|
370 /** Callback for when a GPS update is sent by the AGPS manager. |
|
371 */ |
|
372 void CAgpsInterfaceHandler::OnPositionUpdate( |
|
373 TBool aConflictControl, |
|
374 TInt aReason, |
|
375 const TPositionExtendedSatelliteInfo& aPosInfo, |
|
376 const TTime& aActualTime) |
|
377 { |
|
378 LBSLOG(ELogP1, "CAgpsInterfaceHandler::OnPositionUpdate"); |
|
379 if (CheckPositionUpdateIsValid(aConflictControl, |
|
380 aReason, |
|
381 aPosInfo, |
|
382 aActualTime)) |
|
383 { |
|
384 // Send the update to the PrivLocHandler |
|
385 iObserver.OnAgpsPositionUpdate(aReason, aPosInfo, aActualTime); |
|
386 } |
|
387 } |
|
388 |
|
389 /** Callback for when a GPS Measured Results update is sent by the AGPS manager. |
|
390 */ |
|
391 void CAgpsInterfaceHandler::OnMeasurementInfoUpdate( |
|
392 TInt aReason, |
|
393 const TPositionGpsMeasurementInfo& aMeasurementResults, |
|
394 const TTime& aActualTime) |
|
395 { |
|
396 // Send result to observer |
|
397 iObserver.OnAgpsMeasurementUpdate(aReason, aMeasurementResults, aActualTime); |
|
398 } |
|
399 |
|
400 /** Combines the quality parameters of all the active requests. |
|
401 |
|
402 Note: Only requests which are 'active' should be considered when |
|
403 combining the quality params. |
|
404 */ |
|
405 void CAgpsInterfaceHandler::CalculateCombinedRequestQuality() |
|
406 { |
|
407 // Set the initial values to start from |
|
408 TReal32 minHorizAcc(10000000000000000.0); |
|
409 TReal32 minVertAcc(10000000000000000.0); |
|
410 TTimeIntervalMicroSeconds maxMaxFixTime(0); |
|
411 TTime now; |
|
412 now.UniversalTime(); |
|
413 |
|
414 // Combine each request in turn but only if it is 'active'. |
|
415 const TInt count = iRequests.Count(); |
|
416 for (TInt i = 0; i < count; i++) |
|
417 { |
|
418 if (iRequests[i].iState == EAgpsRequestStateActive) |
|
419 { |
|
420 // Horizontal accuracy = strictest accuracy. |
|
421 minHorizAcc = Min(minHorizAcc, |
|
422 iRequests[i].iPosQuality->MinHorizontalAccuracy()); |
|
423 |
|
424 // Vertical accuracy = strictest accuracy. |
|
425 minVertAcc = Min(minVertAcc, |
|
426 iRequests[i].iPosQuality->MinVerticalAccuracy()); |
|
427 |
|
428 // Max fix time = greatest/longest time. |
|
429 TTimeIntervalMicroSeconds maxFixTime = (iRequests[i].iEndTime.Int64() - now.Int64()); |
|
430 maxMaxFixTime = Max(maxMaxFixTime, maxFixTime); |
|
431 } |
|
432 } |
|
433 |
|
434 // Set the combined accuracy |
|
435 iCombinedRequestQuality.SetMinHorizontalAccuracy(minHorizAcc); |
|
436 iCombinedRequestQuality.SetMinVerticalAccuracy(minVertAcc); |
|
437 iCombinedRequestQuality.SetMaxFixTime(maxMaxFixTime); |
|
438 } |
|
439 |
|
440 /** Calculates the power mode advice to send to the AGPS manager. |
|
441 |
|
442 Use the state of the X3P handler and the combined state of the current |
|
443 requests to calculate the power mode advice to send to the AGPS |
|
444 manager. |
|
445 */ |
|
446 void CAgpsInterfaceHandler::CalculateCombinedPowerModeAdvice( |
|
447 TLbsPositionUpdateRequestBase::TPowerAdvice& aCombinedPowerAdvice) |
|
448 { |
|
449 // Calculate combined state for all requests |
|
450 TAgpsRequestState combinedState(EAgpsRequestStateUnknown); |
|
451 if (IsAnyRequestState(EAgpsRequestStateActive)) |
|
452 { |
|
453 combinedState = EAgpsRequestStateActive; |
|
454 } |
|
455 else if (IsAnyRequestState(EAgpsRequestStateHold)) |
|
456 { |
|
457 combinedState = EAgpsRequestStateHold; |
|
458 } |
|
459 else if (IsAnyRequestState(EAgpsRequestStateIdle)) |
|
460 { |
|
461 combinedState = EAgpsRequestStateIdle; |
|
462 } |
|
463 |
|
464 // Select the power advice to send to the AGPS manager by using |
|
465 // a look-up table. |
|
466 // |
|
467 // The look-up table below is described in the NRH design document, |
|
468 // so if it is changed, the design doc should also be updated to |
|
469 // keep it in sync. |
|
470 const TInt KNumX3pStates = 3; |
|
471 const TInt KNumLocRequestStates = 4; |
|
472 static const TLbsPositionUpdateRequestBase::TPowerAdvice KPowerAdviceTable[KNumX3pStates][KNumLocRequestStates] = |
|
473 { |
|
474 { TLbsPositionUpdateRequestBase::EPowerAdviceOff, |
|
475 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
476 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
477 TLbsPositionUpdateRequestBase::EPowerAdviceOn }, |
|
478 |
|
479 { TLbsPositionUpdateRequestBase::EPowerAdviceStandby, |
|
480 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
481 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
482 TLbsPositionUpdateRequestBase::EPowerAdviceOn }, |
|
483 |
|
484 { TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
485 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
486 TLbsPositionUpdateRequestBase::EPowerAdviceOn, |
|
487 TLbsPositionUpdateRequestBase::EPowerAdviceOn } |
|
488 }; |
|
489 |
|
490 // Note: Because this table uses the enum values directly as indices, |
|
491 // if either enum changes, you need to re-do the table above as well. |
|
492 __ASSERT_ALWAYS(iX3pStatus < KNumX3pStates, Panic(ENrhPanicInvalidPowerModeAdviceIndex)); |
|
493 aCombinedPowerAdvice = KPowerAdviceTable[iX3pStatus][combinedState]; |
|
494 } |
|
495 |
|
496 /** |
|
497 Goes through all requests and decides if the timing of cell frames is requested or not |
|
498 |
|
499 @return ETrue if the timing of cell frames is requested |
|
500 */ |
|
501 TBool CAgpsInterfaceHandler::CalculateCombinedTimingOfCellFramesRequested() |
|
502 { |
|
503 TBool timingOfCellFramesRequested(EFalse); |
|
504 |
|
505 // Combine each request in turn but only if it is 'active'. |
|
506 const TInt count = iRequests.Count(); |
|
507 // Make the flag to be ETrue if there are any requests active or on hold that have the flag |
|
508 // set to ETrue |
|
509 for (TInt i = 0; i < count; i++) |
|
510 { |
|
511 if((iRequests[i].iState == EAgpsRequestStateActive || |
|
512 iRequests[i].iState == EAgpsRequestStateHold) && |
|
513 iRequests[i].iGpsTimingOfCellFramesRequested) |
|
514 { |
|
515 timingOfCellFramesRequested = ETrue; |
|
516 break; |
|
517 } |
|
518 } |
|
519 return timingOfCellFramesRequested; |
|
520 } |
|
521 |
|
522 /** Performs the common actions for sending a location request to the AGPS manager. |
|
523 |
|
524 This function does common tasks such as calculating the power mode to send, |
|
525 starting or stopping the needed monitors and actually sending the combined |
|
526 request. |
|
527 |
|
528 Note: Combining the quality params and/or GPS mode params is done differently |
|
529 depending on whether a request is being started, stopped or put on hold, |
|
530 so that is not done in this function. |
|
531 */ |
|
532 void CAgpsInterfaceHandler::SendCombinedLocationRequest() |
|
533 { |
|
534 // Always start the GPS position update monitor, even in TA mode, |
|
535 // because we use this update bus to listen for error codes, |
|
536 // e.g. KPositionEarlyComplete. |
|
537 iLocationUpdateMonitor->StartMonitor(); |
|
538 |
|
539 // Start measurement monitor if combined request has GPS mode |
|
540 // with Terminal-Assisted or hybrid: |
|
541 if (iCombinedRequestGpsMode == EGpsRequestModeTerminalAssisted |
|
542 || iCombinedRequestGpsMode == EGpsRequestModeHybrid) |
|
543 { |
|
544 iMeasurementUpdateMonitor->StartMonitor(); |
|
545 } |
|
546 else |
|
547 { |
|
548 iMeasurementUpdateMonitor->StopMonitor(); |
|
549 } |
|
550 |
|
551 // Convert the TGpsRequestMode into TLbsNetPosRequestMethodInt |
|
552 TLbsNetPosRequestMethodInt posMethod; |
|
553 posMethod.SetGpsTimingOfCellFramesRequested(CalculateCombinedTimingOfCellFramesRequested()); |
|
554 ConvertGpsRequestModeToPosMethod(iCombinedRequestGpsMode, posMethod); |
|
555 |
|
556 // Calculate the current power advice. |
|
557 CalculateCombinedPowerModeAdvice(iCombinedPowerModeAdvice); |
|
558 |
|
559 // Send combined location request. |
|
560 iLocationUpdateMonitor->SendLocationRequest( |
|
561 iCombinedPowerModeAdvice, |
|
562 posMethod, |
|
563 iCombinedRequestQuality); |
|
564 iLocationRequestActive = ETrue; |
|
565 } |
|
566 |
|
567 /** Called by CX3pHandler tp update the state of X3P requests. |
|
568 |
|
569 For X3P, if there is a client connected to the NRH server, we assume that |
|
570 there will a request soon, so we can send 'standby' power mode advice, to |
|
571 allow the GPS hardware to prepare for a location request before the request |
|
572 has actually arrived. |
|
573 */ |
|
574 void CAgpsInterfaceHandler::SetX3pStatus(MX3pStatusHandler::TX3pStatus aStatus) |
|
575 { |
|
576 // Only send a power advice if the X3P status has actually changed. |
|
577 if (aStatus != iX3pStatus) |
|
578 { |
|
579 iX3pStatus = aStatus; |
|
580 TLbsPositionUpdateRequestBase::TPowerAdvice newPowerAdvice; |
|
581 CalculateCombinedPowerModeAdvice(newPowerAdvice); |
|
582 if (newPowerAdvice != iCombinedPowerModeAdvice) |
|
583 { |
|
584 iCombinedPowerModeAdvice = newPowerAdvice; |
|
585 iLocationUpdateMonitor->SendPowerAdviceRequest(iCombinedPowerModeAdvice); |
|
586 } |
|
587 } |
|
588 } |
|
589 |
|
590 /** Comparison function for use with RArray::Find() |
|
591 |
|
592 @return ETrue if session Ids match, EFalse otherwise. |
|
593 */ |
|
594 TBool CAgpsInterfaceHandler::IsSessionIdEqual( |
|
595 const TLbsNetSessionIdInt* aSessionId, |
|
596 const TAgpsRequest& aRequest) |
|
597 { |
|
598 return (*aSessionId == *aRequest.iSessionId); |
|
599 } |
|
600 |
|
601 /** Comparison function for use with RArray::Find() |
|
602 |
|
603 @return ETrue if states match, EFalse otherwise. |
|
604 */ |
|
605 TBool CAgpsInterfaceHandler::IsRequestStateEqual( |
|
606 const TAgpsRequestState* aState, |
|
607 const TAgpsRequest& aRequest) |
|
608 { |
|
609 return (*aState == aRequest.iState); |
|
610 } |
|
611 |
|
612 /** Add or update a location request in the buffer. |
|
613 |
|
614 If the request already exists on the list then its parameters are updated. |
|
615 If it doesn't exist then the request is appended to the list. |
|
616 For emergencies we haveone reserved slot used just for the emergency location request |
|
617 */ |
|
618 TInt CAgpsInterfaceHandler::AddOrUpdateRequest(const TAgpsRequest& aRequest, TBool aEmergency) |
|
619 { |
|
620 TInt err(KErrNone); |
|
621 TInt index = iRequests.Find(*aRequest.iSessionId, IsSessionIdEqual); |
|
622 if (index >= 0) |
|
623 { |
|
624 // Update params of existing request |
|
625 iRequests[index] = aRequest; |
|
626 } |
|
627 else if (aEmergency) |
|
628 { |
|
629 // Note that we can guarantee at least ONE free slot. See below. |
|
630 // add emergency request to list |
|
631 err = iRequests.Append(aRequest); |
|
632 } |
|
633 else if (iRequests.Count() <= iMaxNumLocationRequests) |
|
634 { |
|
635 // Add new request to iRequests. Note, only allocate up to |
|
636 // iMaxNumLocationRequests slots and leave at least one free for use for emergency |
|
637 err = iRequests.Append(aRequest); |
|
638 } |
|
639 else |
|
640 { |
|
641 // Exceeded the max number of requests, reject it! |
|
642 LBSLOG_ERR3(ELogP3, |
|
643 "CAgpsInterfaceHandler::AddOrUpdateRequest: Can't add new request, active requests (%d), limit (%d)", |
|
644 iRequests.Count(), |
|
645 iMaxNumLocationRequests); |
|
646 return KErrInUse; |
|
647 } |
|
648 return err; |
|
649 } |
|
650 |
|
651 /** Remove a request from the buffer. |
|
652 |
|
653 @param aSessionId SessionId of the request to remove. |
|
654 */ |
|
655 void CAgpsInterfaceHandler::RemoveRequest(const TLbsNetSessionIdInt& aSessionId) |
|
656 { |
|
657 TInt index = iRequests.Find(aSessionId, IsSessionIdEqual); |
|
658 if (index >= 0) |
|
659 { |
|
660 iRequests.Remove(index); |
|
661 } |
|
662 else |
|
663 { |
|
664 LBSLOG_WARN2(ELogP3, "CAgpsInterfaceHandler::RemoveRequest: Failed to find match for sessionId %d.", aSessionId.SessionNum()); |
|
665 } |
|
666 } |
|
667 |
|
668 /** Search to find if any requests' state matches the given state. |
|
669 |
|
670 @param aState Request state to compare to. |
|
671 |
|
672 @return ETrue if any state has a matching state. EFalse otherwise. |
|
673 */ |
|
674 TBool CAgpsInterfaceHandler::IsAnyRequestState( |
|
675 TAgpsRequestState aState) |
|
676 { |
|
677 TInt index = iRequests.Find(aState, IsRequestStateEqual); |
|
678 return (index >= 0); |
|
679 } |
|
680 |
|
681 /** Convert a TLbsNetPosRequestMethodInt into a TGpsRequestMode enum. |
|
682 */ |
|
683 TGpsRequestMode CAgpsInterfaceHandler::ConvertPosMethodToGpsRequestMode( |
|
684 const TLbsNetPosRequestMethodInt& aPosMethod) |
|
685 { |
|
686 TGpsRequestMode gpsMode(EGpsRequestModeUnknown); |
|
687 |
|
688 const TInt count = aPosMethod.NumPosMethods(); |
|
689 for (TInt i = 0; i < count; i++) |
|
690 { |
|
691 TLbsNetPosMethodInt method; |
|
692 aPosMethod.GetPosMethod(i, method); |
|
693 switch (method.PosMode()) |
|
694 { |
|
695 case KAutonomousMode: |
|
696 { |
|
697 if (gpsMode == EGpsRequestModeTerminalAssisted) |
|
698 { |
|
699 gpsMode = EGpsRequestModeHybrid; |
|
700 } |
|
701 else |
|
702 { |
|
703 gpsMode = EGpsRequestModeAutonomous; |
|
704 } |
|
705 break; |
|
706 } |
|
707 case KTerminalBasedMode: |
|
708 { |
|
709 if (gpsMode == EGpsRequestModeTerminalAssisted) |
|
710 { |
|
711 gpsMode = EGpsRequestModeHybrid; |
|
712 } |
|
713 else |
|
714 { |
|
715 gpsMode = EGpsRequestModeTerminalBased; |
|
716 } |
|
717 break; |
|
718 } |
|
719 case KTerminalAssistedMode: |
|
720 { |
|
721 if (gpsMode == EGpsRequestModeTerminalBased |
|
722 || gpsMode == EGpsRequestModeAutonomous) |
|
723 { |
|
724 gpsMode = EGpsRequestModeHybrid; |
|
725 } |
|
726 else |
|
727 { |
|
728 gpsMode = EGpsRequestModeTerminalAssisted; |
|
729 } |
|
730 break; |
|
731 } |
|
732 } |
|
733 } |
|
734 |
|
735 return gpsMode; |
|
736 } |
|
737 |
|
738 |
|
739 /** Convert a TGpsRequestMode enum into a TLbsNetPosRequestMethodInt. |
|
740 */ |
|
741 void CAgpsInterfaceHandler::ConvertGpsRequestModeToPosMethod( |
|
742 TGpsRequestMode aMode, |
|
743 TLbsNetPosRequestMethodInt& aPosMethod) |
|
744 { |
|
745 TLbsNetPosMethodInt methods[2]; |
|
746 switch (aMode) |
|
747 { |
|
748 case EGpsRequestModeAutonomous: |
|
749 { |
|
750 methods[0].SetPosMethod(KLbsPositioningMeansGpsInt, KAutonomousMode); |
|
751 aPosMethod.SetPosMethods(methods, 1); |
|
752 break; |
|
753 } |
|
754 case EGpsRequestModeTerminalBased: |
|
755 { |
|
756 methods[0].SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalBasedMode); |
|
757 aPosMethod.SetPosMethods(methods, 1); |
|
758 break; |
|
759 } |
|
760 case EGpsRequestModeTerminalAssisted: |
|
761 { |
|
762 methods[0].SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalAssistedMode); |
|
763 aPosMethod.SetPosMethods(methods, 1); |
|
764 break; |
|
765 } |
|
766 case EGpsRequestModeHybrid: |
|
767 { |
|
768 methods[0].SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalBasedMode); |
|
769 methods[1].SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalAssistedMode); |
|
770 aPosMethod.SetPosMethods(methods, 2); |
|
771 break; |
|
772 } |
|
773 |
|
774 case EGpsRequestModeUnknown: |
|
775 default: |
|
776 { |
|
777 GetDefaultPosMethod(aPosMethod); |
|
778 break; |
|
779 } |
|
780 } |
|
781 |
|
782 } |
|
783 |
|
784 /** Calculate the new combined GPS mode when a new request is added. |
|
785 |
|
786 The new combined GPS mode depends on a combination of: |
|
787 1) The GPS mode(s) the module supports. |
|
788 2) The current combined GPS mode. |
|
789 3) The GPS mode of the new request. |
|
790 |
|
791 @param aCurrentPosMethod [In] The GPS mode of the current combined request. |
|
792 @param aNewRequestPosMethod [In] The GPS mode of the new request. |
|
793 @param aCurrentPosMethod [Out] The GPS mode of the newly combined requests. |
|
794 |
|
795 @return KErrNone if the GPS mode was combined successfully, KErrNotSupported |
|
796 if the GPS mode of the new request is not supported by the GPS module, |
|
797 KErrInUse if the new request GPS mode clashes with the current combined |
|
798 request GPS mode, e.g. if the module supports either TA or TB, but not |
|
799 both and the new request is TB but the current request is TA. |
|
800 */ |
|
801 TInt CAgpsInterfaceHandler::CalculateNewCombinedRequestMethod( |
|
802 TGpsRequestMode aCurrentGpsMode, |
|
803 TGpsRequestMode aNewRequestGpsMode, |
|
804 TGpsRequestMode& aCombinedGpsMode, |
|
805 TBool aEmergency) |
|
806 { |
|
807 // Table entry |
|
808 struct TGpsModeTableEntry |
|
809 { |
|
810 TGpsRequestMode iCurrentGpsMode; |
|
811 TGpsRequestMode iNewRequestGpsMode; |
|
812 TGpsRequestMode iCombinedGpsMode; |
|
813 TInt iErrorCode; |
|
814 }; |
|
815 |
|
816 // Each of the tables below are taken directly from the |
|
817 // NRH design document. If any of them are changed (e.g. |
|
818 // for a defect fix), the table in the design doc should |
|
819 // also be updated to match. |
|
820 |
|
821 // Module supports Terminal-Based only. |
|
822 static const TGpsModeTableEntry KGpsModeCombinationTableTB[] = |
|
823 { |
|
824 // Current request mode // New request mode // Newly combined request mode // Error |
|
825 {EGpsRequestModeUnknown, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
826 {EGpsRequestModeUnknown, EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, KErrNone}, |
|
827 {EGpsRequestModeUnknown, EGpsRequestModeTerminalAssisted,EGpsRequestModeUnknown, KErrNotSupported}, |
|
828 {EGpsRequestModeUnknown, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
829 |
|
830 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
831 {EGpsRequestModeAutonomous, EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, KErrNone}, |
|
832 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalAssisted,EGpsRequestModeUnknown, KErrNotSupported}, |
|
833 {EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
834 |
|
835 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
836 {EGpsRequestModeTerminalBased, EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, KErrNone}, |
|
837 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalAssisted,EGpsRequestModeUnknown, KErrNotSupported}, |
|
838 {EGpsRequestModeTerminalBased, EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, KErrNone} |
|
839 }; |
|
840 static const TInt KGpsModeCombinationTableTBCount(sizeof(KGpsModeCombinationTableTB) |
|
841 / sizeof(TGpsModeTableEntry)); |
|
842 |
|
843 // Module supports Terminal-Assisted only. |
|
844 static const TGpsModeTableEntry KGpsModeCombinationTableTA[] = |
|
845 { |
|
846 {EGpsRequestModeUnknown, EGpsRequestModeTerminalBased, EGpsRequestModeUnknown, KErrNotSupported}, |
|
847 {EGpsRequestModeUnknown, EGpsRequestModeHybrid, EGpsRequestModeTerminalAssisted,KErrNone}, |
|
848 {EGpsRequestModeUnknown, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
849 {EGpsRequestModeUnknown, EGpsRequestModeAutonomous, EGpsRequestModeUnknown, KErrNotSupported}, |
|
850 |
|
851 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalBased, EGpsRequestModeUnknown, KErrNotSupported}, |
|
852 {EGpsRequestModeTerminalAssisted, EGpsRequestModeHybrid, EGpsRequestModeTerminalAssisted,KErrNone}, |
|
853 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
854 {EGpsRequestModeTerminalAssisted, EGpsRequestModeAutonomous, EGpsRequestModeUnknown, KErrNotSupported} |
|
855 }; |
|
856 static const TInt KGpsModeCombinationTableTACount(sizeof(KGpsModeCombinationTableTA) |
|
857 / sizeof(TGpsModeTableEntry)); |
|
858 |
|
859 // Module supports either Terminal-Assisted or Terminal-Based (but not both at the same time). |
|
860 static const TGpsModeTableEntry KGpsModeCombinationTableTBOrTA[] = |
|
861 { |
|
862 {EGpsRequestModeUnknown, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
863 {EGpsRequestModeUnknown, EGpsRequestModeHybrid, EGpsSpecialTreatmentForHybrid, KErrNone}, |
|
864 {EGpsRequestModeUnknown, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
865 {EGpsRequestModeUnknown, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
866 |
|
867 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
868 {EGpsRequestModeAutonomous, EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, KErrNone}, |
|
869 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalAssisted,EGpsRequestModeUnknown, KErrInUse}, |
|
870 {EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
871 |
|
872 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
873 {EGpsRequestModeTerminalBased, EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, KErrNone}, |
|
874 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalAssisted,EGpsRequestModeUnknown, KErrInUse}, |
|
875 {EGpsRequestModeTerminalBased, EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, KErrNone}, |
|
876 |
|
877 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalBased, EGpsRequestModeUnknown, KErrInUse}, |
|
878 {EGpsRequestModeTerminalAssisted, EGpsRequestModeHybrid, EGpsRequestModeTerminalAssisted,KErrNone}, |
|
879 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
880 {EGpsRequestModeTerminalAssisted, EGpsRequestModeAutonomous, EGpsRequestModeUnknown, KErrInUse} |
|
881 }; |
|
882 static const TInt KGpsModeCombinationTableTBOrTACount(sizeof(KGpsModeCombinationTableTBOrTA) |
|
883 / sizeof(TGpsModeTableEntry)); |
|
884 |
|
885 // Module supports Terminal-Assisted and Terminal-Base simultaneously. |
|
886 static const TGpsModeTableEntry KGpsModeCombinationTableTBAndTA[] = |
|
887 { |
|
888 {EGpsRequestModeUnknown, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
889 {EGpsRequestModeUnknown, EGpsRequestModeHybrid, EGpsRequestModeHybrid, KErrNone}, |
|
890 {EGpsRequestModeUnknown, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
891 {EGpsRequestModeUnknown, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
892 |
|
893 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
894 {EGpsRequestModeAutonomous, EGpsRequestModeHybrid, EGpsRequestModeHybrid, KErrNone}, |
|
895 {EGpsRequestModeAutonomous, EGpsRequestModeTerminalAssisted,EGpsRequestModeHybrid, KErrNone}, |
|
896 {EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, EGpsRequestModeAutonomous, KErrNone}, |
|
897 |
|
898 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, EGpsRequestModeTerminalBased, KErrNone}, |
|
899 {EGpsRequestModeTerminalBased, EGpsRequestModeHybrid, EGpsRequestModeHybrid, KErrNone}, |
|
900 {EGpsRequestModeTerminalBased, EGpsRequestModeTerminalAssisted,EGpsRequestModeHybrid, KErrNone}, |
|
901 {EGpsRequestModeTerminalBased, EGpsRequestModeAutonomous, EGpsRequestModeTerminalBased, KErrNone}, |
|
902 |
|
903 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalBased, EGpsRequestModeHybrid, KErrNone}, |
|
904 {EGpsRequestModeTerminalAssisted, EGpsRequestModeHybrid, EGpsRequestModeHybrid, KErrNone}, |
|
905 {EGpsRequestModeTerminalAssisted, EGpsRequestModeTerminalAssisted,EGpsRequestModeTerminalAssisted,KErrNone}, |
|
906 {EGpsRequestModeTerminalAssisted, EGpsRequestModeAutonomous, EGpsRequestModeHybrid, KErrNone}, |
|
907 |
|
908 {EGpsRequestModeHybrid, EGpsRequestModeTerminalBased, EGpsRequestModeHybrid, KErrNone}, |
|
909 {EGpsRequestModeHybrid, EGpsRequestModeHybrid, EGpsRequestModeHybrid, KErrNone}, |
|
910 {EGpsRequestModeHybrid, EGpsRequestModeTerminalAssisted,EGpsRequestModeHybrid, KErrNone}, |
|
911 {EGpsRequestModeHybrid, EGpsRequestModeAutonomous, EGpsRequestModeHybrid, KErrNone} |
|
912 }; |
|
913 static const TInt KGpsModeCombinationTableTBAndTACount(sizeof(KGpsModeCombinationTableTBAndTA) |
|
914 / sizeof(TGpsModeTableEntry)); |
|
915 |
|
916 // Decide which table to use |
|
917 const TGpsModeTableEntry* modeTable(NULL); |
|
918 TInt modeEntryCount(0); |
|
919 switch (iDeviceGpsModeCaps) |
|
920 { |
|
921 case TPositionModuleInfoExtended::EDeviceGpsModeTerminalBased: |
|
922 { |
|
923 modeTable = KGpsModeCombinationTableTB; |
|
924 modeEntryCount = KGpsModeCombinationTableTBCount; |
|
925 break; |
|
926 } |
|
927 case TPositionModuleInfoExtended::EDeviceGpsModeTerminalAssisted: |
|
928 { |
|
929 modeTable = KGpsModeCombinationTableTA; |
|
930 modeEntryCount = KGpsModeCombinationTableTACount; |
|
931 break; |
|
932 } |
|
933 case (TPositionModuleInfoExtended::EDeviceGpsModeTerminalBased |
|
934 | TPositionModuleInfoExtended::EDeviceGpsModeTerminalAssisted): |
|
935 { |
|
936 modeTable = KGpsModeCombinationTableTBOrTA; |
|
937 modeEntryCount = KGpsModeCombinationTableTBOrTACount; |
|
938 break; |
|
939 } |
|
940 case TPositionModuleInfoExtended::EDeviceGpsModeSimultaneousTATB: |
|
941 { |
|
942 modeTable = KGpsModeCombinationTableTBAndTA; |
|
943 modeEntryCount = KGpsModeCombinationTableTBAndTACount; |
|
944 break; |
|
945 } |
|
946 } |
|
947 |
|
948 // Search the table to find a matching entry and get the new combined mode |
|
949 aCombinedGpsMode = EGpsRequestModeUnknown; |
|
950 TInt combinedReason(KErrNotSupported); |
|
951 if (modeTable) |
|
952 { |
|
953 for (TInt i = 0; i < modeEntryCount; i++) |
|
954 { |
|
955 if (modeTable->iCurrentGpsMode == aCurrentGpsMode |
|
956 && modeTable->iNewRequestGpsMode == aNewRequestGpsMode) |
|
957 { |
|
958 aCombinedGpsMode = modeTable->iCombinedGpsMode; |
|
959 combinedReason = modeTable->iErrorCode; |
|
960 break; |
|
961 } |
|
962 |
|
963 modeTable++; |
|
964 } |
|
965 } |
|
966 |
|
967 if (aEmergency && (combinedReason == KErrInUse)) |
|
968 { |
|
969 combinedReason = KErrNone; |
|
970 aCombinedGpsMode = aNewRequestGpsMode; |
|
971 |
|
972 } |
|
973 else if (combinedReason == KErrNone && aCombinedGpsMode == EGpsSpecialTreatmentForHybrid) |
|
974 { |
|
975 TLbsNetPosRequestMethodInt posMethod; |
|
976 GetPosSpecialTeatmentForHybrid(posMethod); |
|
977 aCombinedGpsMode = ConvertPosMethodToGpsRequestMode(posMethod); |
|
978 } |
|
979 else if (combinedReason == KErrNone && aCombinedGpsMode == EGpsRequestModeUnknown) |
|
980 |
|
981 { |
|
982 // If the new combined mode is not set but there was no error, |
|
983 // it means we should use the default mode from the admin settings. |
|
984 TLbsNetPosRequestMethodInt posMethod; |
|
985 GetDefaultPosMethod(posMethod); |
|
986 aCombinedGpsMode = ConvertPosMethodToGpsRequestMode(posMethod); |
|
987 } |
|
988 |
|
989 |
|
990 return combinedReason; |
|
991 } |
|
992 |
|
993 |
|
994 /** Get GPS positioning mode based on admin settings for the case |
|
995 * when the capabiliies are TA or TB but a hybrid request has arrived. |
|
996 |
|
997 @param aPosMethod The default positioning method is written in to this parameter. |
|
998 |
|
999 @return KErrNone usually, but one of the standard Symbian OS error codes if there |
|
1000 was an error obtaining the positioning method. |
|
1001 */ |
|
1002 void CAgpsInterfaceHandler::GetPosSpecialTeatmentForHybrid(TLbsNetPosRequestMethodInt& aPosMethod) |
|
1003 { |
|
1004 |
|
1005 // Get the current network registration status. |
|
1006 RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus status; |
|
1007 TLbsAdminSetting setting; |
|
1008 TInt err = iNetRegStatus.GetNetworkRegistrationStatus(status); |
|
1009 if (KErrNone != err) |
|
1010 { |
|
1011 LBSLOG_WARN(ELogP3, |
|
1012 "CAgpsInterfaceHandler::GetDefaultPosMethod: Failed to read network registration status, using RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown"); |
|
1013 status = RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown; |
|
1014 } |
|
1015 |
|
1016 switch (status) |
|
1017 { |
|
1018 case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork: |
|
1019 { |
|
1020 setting = KLbsSettingHomeGpsMode; |
|
1021 break; |
|
1022 } |
|
1023 case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork: |
|
1024 case RLbsNetworkRegistrationStatus::ENotRegistered: |
|
1025 case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown: |
|
1026 default: |
|
1027 { |
|
1028 setting = KLbsSettingRoamingGpsMode; |
|
1029 break; |
|
1030 } |
|
1031 } |
|
1032 |
|
1033 // Get the default mode from admin settings. |
|
1034 CLbsAdmin::TGpsMode gpsMode; |
|
1035 err = iAdmin.Get(setting, gpsMode); |
|
1036 if (KErrNone != err) |
|
1037 { |
|
1038 LBSLOG_WARN2(ELogP3, |
|
1039 "CAgpsInterfaceHandler::GetDefaultPosMethod: Failed to read admin setting: 0x%x, using CLbsAdmin::EGpsModeUnknown", |
|
1040 setting); |
|
1041 gpsMode = CLbsAdmin::EGpsModeUnknown; |
|
1042 } |
|
1043 |
|
1044 switch (gpsMode) |
|
1045 { |
|
1046 |
|
1047 case CLbsAdmin::EGpsAutonomous: |
|
1048 case CLbsAdmin::EGpsPreferTerminalBased: |
|
1049 case CLbsAdmin::EGpsAlwaysTerminalBased: |
|
1050 { |
|
1051 TLbsNetPosMethodInt methodTB; |
|
1052 methodTB.SetPosMethod(KLbsPositioningMeansGps, KTerminalBasedMode); |
|
1053 aPosMethod.SetPosMethods(&methodTB, 1); |
|
1054 break; |
|
1055 } |
|
1056 case CLbsAdmin::EGpsPreferTerminalAssisted: |
|
1057 case CLbsAdmin::EGpsAlwaysTerminalAssisted: |
|
1058 { |
|
1059 TLbsNetPosMethodInt methodTA; |
|
1060 methodTA.SetPosMethod(KLbsPositioningMeansGps, KTerminalAssistedMode); |
|
1061 aPosMethod.SetPosMethods(&methodTA, 1); |
|
1062 break; |
|
1063 } |
|
1064 |
|
1065 default: |
|
1066 { |
|
1067 // Default to terminal based mode. |
|
1068 TLbsNetPosMethodInt methodTB; |
|
1069 methodTB.SetPosMethod(KLbsPositioningMeansGps, KTerminalBasedMode); |
|
1070 aPosMethod.SetPosMethods(&methodTB, 1); |
|
1071 break; |
|
1072 } |
|
1073 } |
|
1074 } |
|
1075 /** Get the default GPS positioning mode, based on admin settings, etc. |
|
1076 |
|
1077 @param aPosMethod The default positioning method is written in to this parameter. |
|
1078 |
|
1079 @return KErrNone usually, but one of the standard Symbian OS error codes if there |
|
1080 was an error obtaining the default positioning method. |
|
1081 */ |
|
1082 void CAgpsInterfaceHandler::GetDefaultPosMethod(TLbsNetPosRequestMethodInt& aPosMethod) |
|
1083 { |
|
1084 |
|
1085 // Get the current network registration status. |
|
1086 RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus status; |
|
1087 TLbsAdminSetting setting; |
|
1088 TInt err = iNetRegStatus.GetNetworkRegistrationStatus(status); |
|
1089 if (KErrNone != err) |
|
1090 { |
|
1091 LBSLOG_WARN(ELogP3, |
|
1092 "CAgpsInterfaceHandler::GetDefaultPosMethod: Failed to read network registration status, using RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown"); |
|
1093 status = RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown; |
|
1094 } |
|
1095 |
|
1096 switch (status) |
|
1097 { |
|
1098 case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork: |
|
1099 { |
|
1100 setting = KLbsSettingHomeGpsMode; |
|
1101 break; |
|
1102 } |
|
1103 case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork: |
|
1104 case RLbsNetworkRegistrationStatus::ENotRegistered: |
|
1105 case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown: |
|
1106 default: |
|
1107 { |
|
1108 setting = KLbsSettingRoamingGpsMode; |
|
1109 break; |
|
1110 } |
|
1111 } |
|
1112 |
|
1113 // Get the default mode from admin settings. |
|
1114 CLbsAdmin::TGpsMode gpsMode; |
|
1115 err = iAdmin.Get(setting, gpsMode); |
|
1116 if (KErrNone != err) |
|
1117 { |
|
1118 LBSLOG_WARN2(ELogP3, |
|
1119 "CAgpsInterfaceHandler::GetDefaultPosMethod: Failed to read admin setting: 0x%x, using CLbsAdmin::EGpsModeUnknown", |
|
1120 setting); |
|
1121 gpsMode = CLbsAdmin::EGpsModeUnknown; |
|
1122 } |
|
1123 |
|
1124 switch (gpsMode) |
|
1125 { |
|
1126 case CLbsAdmin::EGpsPreferTerminalBased: |
|
1127 case CLbsAdmin::EGpsAlwaysTerminalBased: |
|
1128 { |
|
1129 TLbsNetPosMethodInt methodTB; |
|
1130 methodTB.SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalBasedMode); |
|
1131 aPosMethod.SetPosMethods(&methodTB, 1); |
|
1132 break; |
|
1133 } |
|
1134 case CLbsAdmin::EGpsPreferTerminalAssisted: |
|
1135 case CLbsAdmin::EGpsAlwaysTerminalAssisted: |
|
1136 { |
|
1137 TLbsNetPosMethodInt methodTA; |
|
1138 methodTA.SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalAssistedMode); |
|
1139 aPosMethod.SetPosMethods(&methodTA, 1); |
|
1140 break; |
|
1141 } |
|
1142 case CLbsAdmin::EGpsAutonomous: |
|
1143 { |
|
1144 TLbsNetPosMethodInt methodA; |
|
1145 methodA.SetPosMethod(KLbsPositioningMeansGpsInt, KAutonomousMode); |
|
1146 aPosMethod.SetPosMethods(&methodA, 1); |
|
1147 break; |
|
1148 } |
|
1149 default: |
|
1150 { |
|
1151 // Default to terminal based mode. |
|
1152 TLbsNetPosMethodInt methodTB; |
|
1153 methodTB.SetPosMethod(KLbsPositioningMeansGpsInt, KTerminalBasedMode); |
|
1154 aPosMethod.SetPosMethods(&methodTB, 1); |
|
1155 break; |
|
1156 } |
|
1157 } |
|
1158 } |
|
1159 |