|
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 // |
|
15 |
|
16 #include <e32std.h> |
|
17 #include <e32property.h> |
|
18 #include <centralrepository.h> |
|
19 |
|
20 #ifdef SYMBIAN_FEATURE_MANAGER |
|
21 #include <featdiscovery.h> |
|
22 #include <featureuids.h> |
|
23 #endif |
|
24 |
|
25 // LBS-specific |
|
26 #include <lbs.h> |
|
27 #include <lbs/lbsadmin.h> |
|
28 #include <lbs/lbslocerrors.h> |
|
29 #include <lbs/lbslocclasstypes.h> |
|
30 |
|
31 #include "nrhpanic.h" |
|
32 #include "lbsdevloggermacros.h" |
|
33 #include "lbsqualityprofile.h" |
|
34 #include "lbsrootcenrepdefs.h" |
|
35 #include "lbspositioningstatusprops.h" |
|
36 |
|
37 #include "privacyandlocationrequesthandler.h" |
|
38 |
|
39 // Special 'invalid session' SessionId. |
|
40 const TLbsNetSessionIdInt KInvalidSessionId(TUid::Uid(0), 0); |
|
41 |
|
42 const TPositionModuleInfo::TTechnologyType KTerminalAssistedMode = (TPositionModuleInfo::ETechnologyNetwork | |
|
43 TPositionModuleInfo::ETechnologyAssisted); |
|
44 |
|
45 // ----------------------------------------------------------------------------- |
|
46 // |
|
47 // ----------------------- Class CPrivacyAndLocationHandler -------------------- |
|
48 // |
|
49 // State Machine class which owns the states of the Privacy and Location Handler |
|
50 // |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 |
|
54 // ----------------------------------------------------------------------------- |
|
55 // CPrivacyAndLocationHandler::NewL |
|
56 // Description: CPrivacyAndLocationHandler static constructor |
|
57 // ----------------------------------------------------------------------------- |
|
58 // |
|
59 CPrivacyAndLocationHandler* CPrivacyAndLocationHandler::NewL(CNGMessageSwitch& aMessageSwitch, |
|
60 CLbsAdmin& aLbsAdmin, |
|
61 RLbsNetworkRegistrationStatus& aNetRegStatus) |
|
62 { |
|
63 CPrivacyAndLocationHandler* self; |
|
64 self = new (ELeave) CPrivacyAndLocationHandler(aMessageSwitch, aNetRegStatus); |
|
65 CleanupStack::PushL(self); |
|
66 self->ConstructL(&aLbsAdmin); |
|
67 CleanupStack::Pop(self); |
|
68 return(self); |
|
69 } |
|
70 |
|
71 // ----------------------------------------------------------------------------- |
|
72 // CPrivacyAndLocationHandler::CPrivacyAndLocationHandler |
|
73 // Description: CPrivacyAndLocationHandler constructor |
|
74 // ----------------------------------------------------------------------------- |
|
75 // |
|
76 CPrivacyAndLocationHandler::CPrivacyAndLocationHandler(CNGMessageSwitch& aMessageSwitch, |
|
77 RLbsNetworkRegistrationStatus& aNetRegStatus) |
|
78 : iNetRegStatus(aNetRegStatus), |
|
79 iMessageSwitch(&aMessageSwitch), |
|
80 iNumActiveSessions(0) |
|
81 { |
|
82 } |
|
83 |
|
84 // ----------------------------------------------------------------------------- |
|
85 // CPrivacyAndLocationHandler::~CPrivacyAndLocationHandler |
|
86 // Description: CPrivacyAndLocationHandler destructor |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 CPrivacyAndLocationHandler::~CPrivacyAndLocationHandler() |
|
90 { |
|
91 // If iEmergencyFsm has been used by any outstanding request, |
|
92 // it needs to be removed before calling ResetAndDestroy(), |
|
93 // otherwise it will get double-deleted when delete iEmergencyFsm |
|
94 // is called. |
|
95 |
|
96 TInt index = iFsmArray.Find(iEmergencyFsm); |
|
97 if (index >= 0) |
|
98 { |
|
99 iFsmArray.Remove(index); |
|
100 } |
|
101 |
|
102 iFsmArray.ResetAndDestroy(); |
|
103 |
|
104 // force the count of active network initiated positioning sessions to 0 |
|
105 // this supports the pre-APE centric architecture wherein the NRH is |
|
106 // destroyed on completion of network initiated positioning. |
|
107 RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, 0); |
|
108 |
|
109 delete iEmergencyFsm; |
|
110 delete iAgpsInterface; |
|
111 delete iPrivacyHandler; |
|
112 } |
|
113 |
|
114 // ----------------------------------------------------------------------------- |
|
115 // CPrivacyAndLocationHandler::ConstructL |
|
116 // Description: CPrivacyAndLocationHandler second-phase constructor. |
|
117 // Creates the states of the system and the Privacy Handler. |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 |
|
121 const TInt KLbsDefaultMaxNumLocationRequests = 4; |
|
122 |
|
123 void CPrivacyAndLocationHandler::ConstructL(CLbsAdmin* aLbsAdmin) |
|
124 { |
|
125 iLbsAdmin = aLbsAdmin; |
|
126 |
|
127 iPrivacyHandler = CPrivacyHandler::CreateL(this, *iLbsAdmin, iNetRegStatus); |
|
128 iMessageSwitch->RegisterObserver(this); |
|
129 |
|
130 // Get the behaviour mode and device gps mode capabilities |
|
131 TInt err = iLbsAdmin->Get(KLbsSettingBehaviourMode, iLbsBehaviourMode); |
|
132 if (err != KErrNone) |
|
133 { |
|
134 iLbsBehaviourMode = CLbsAdmin::ELbsBehaviourCustom1; |
|
135 } |
|
136 // get device mode capabilities: |
|
137 err = LbsModuleInfo::GetDeviceCapabilities(KLbsGpsLocManagerUid, iDeviceGpsModeCaps); |
|
138 if(err != KErrNone || (iDeviceGpsModeCaps==TPositionModuleInfoExtended::EDeviceGpsModeNone)) |
|
139 { |
|
140 // Assume module supports hybrid if it has not reported its capabilities in module info file |
|
141 iDeviceGpsModeCaps = TPositionModuleInfoExtended::EDeviceGpsModeSimultaneousTATB; |
|
142 } |
|
143 |
|
144 |
|
145 err = iLbsAdmin->Get(KLbsSettingMaximumExternalLocateRequests, iMaxNumSessions); |
|
146 if (err != KErrNone) |
|
147 { |
|
148 iMaxNumSessions = KLbsDefaultMaxNumLocationRequests; |
|
149 } |
|
150 |
|
151 iAgpsInterface = CAgpsInterfaceHandler::NewL(*this, *iLbsAdmin, iNetRegStatus); |
|
152 |
|
153 |
|
154 #ifdef NRH_UNIT_TEST |
|
155 // For testing use the Uid of the dummy NG |
|
156 const TInt KTestNgUidInt = 0x1028226B; |
|
157 const TUid KTestNgUid = {KTestNgUidInt}; |
|
158 iProtocolModuleUid = KTestNgUid; |
|
159 #else |
|
160 ReadProtocolModuleAdminSetting(); |
|
161 #endif |
|
162 |
|
163 iEmergencyFsm = CLbsPrivLocFsm::NewL(*this, KInvalidSessionId); |
|
164 |
|
165 // Reserve space for FSMs. Note "+1" because a pointer to the emergency Fsm gets added to this array |
|
166 iFsmArray.ReserveL(iMaxNumSessions+1); |
|
167 |
|
168 CLbsAdmin::TSpecialFeature specialFeature(CLbsAdmin::ESpecialFeatureOff); |
|
169 err = iLbsAdmin->Get(KLbsSpecialFeatureIntermediateFutileUpdate, specialFeature); |
|
170 if (err != KErrNone) |
|
171 { |
|
172 LBSLOG_ERR2(ELogP3, "Failed to get KLbsSpecialFeatureIntermediateFutileUpdate (err %d)", err); |
|
173 } |
|
174 LBSLOG2(ELogP3, "Using KLbsSpecialFeatureIntermediateFutileUpdate = %d", specialFeature); |
|
175 iSpecialFeatureIntermediateFutileUpdate = (specialFeature == CLbsAdmin::ESpecialFeatureOn) ? ETrue : EFalse; |
|
176 |
|
177 #ifdef SYMBIAN_FEATURE_MANAGER |
|
178 iLocationManagementSupported = CFeatureDiscovery::IsFeatureSupportedL(NFeature::KLocationManagement); |
|
179 #else |
|
180 __ASSERT_ALWAYS(EFalse, User::Invariant()); // Would happen on older versions of symbian OS if this code ever backported |
|
181 #endif |
|
182 |
|
183 // Get the CategoryUid from the cenrep file owned by LbsRoot for accessing Positioning Status P&S Keys |
|
184 CRepository* rep = CRepository::NewLC(KLbsCenRepUid); |
|
185 TInt posStatusCategory; |
|
186 err = rep->Get(KNiPositioningStatusAPIKey, posStatusCategory); |
|
187 User::LeaveIfError(err); |
|
188 CleanupStack::PopAndDestroy(rep); |
|
189 iPosStatusCategory = TUid::Uid(posStatusCategory); |
|
190 } |
|
191 |
|
192 |
|
193 |
|
194 /** |
|
195 Reads the Uid of a current Protocol Module from the Admin Settings. |
|
196 */ |
|
197 void CPrivacyAndLocationHandler::ReadProtocolModuleAdminSetting() |
|
198 { |
|
199 LBSLOG(ELogP1, "CPrivacyAndLocationHandler::ReadProtocolModuleAdminSetting()"); |
|
200 TLbsProtocolModuleId protUid(KLbsProtocolNullModuleId); |
|
201 |
|
202 TInt err = iLbsAdmin->Get(KLbsSettingHomeProtocolModule, protUid); |
|
203 if (err != KErrNone) |
|
204 { |
|
205 LBSLOG_ERR2(ELogP4, "Failed to get KLbsSettingHomeProtocolModule (err %d)", err); |
|
206 } |
|
207 |
|
208 iProtocolModuleUid = protUid; |
|
209 } |
|
210 |
|
211 /** Compares sessionId for RPointerArray::Find(). |
|
212 */ |
|
213 TBool CPrivacyAndLocationHandler::IsSessionIdEqual( |
|
214 const TLbsNetSessionIdInt* aSessionId, |
|
215 const CLbsPrivLocFsm& aFsm) |
|
216 { |
|
217 return (*aSessionId == aFsm.SessionId()); |
|
218 } |
|
219 |
|
220 /** Compares session type for RPointerArray::Find(). |
|
221 */ |
|
222 TBool CPrivacyAndLocationHandler::IsSessionTypeEqual( |
|
223 const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt* aSessionType, |
|
224 const CLbsPrivLocFsm& aFsm) |
|
225 { |
|
226 return (*aSessionType == const_cast<CLbsPrivLocFsm&>(aFsm).SessionType()); |
|
227 } |
|
228 |
|
229 // ----------------------------------------------------------------------------- |
|
230 // CPrivacyAndLocationHandler::LookupFsm |
|
231 // Description: Lookup CLbsPrivLocFsm object by session ID. |
|
232 // ----------------------------------------------------------------------------- |
|
233 // |
|
234 CLbsPrivLocFsm* CPrivacyAndLocationHandler::LookupFsm(const TLbsNetSessionIdInt& aSessionId) |
|
235 { |
|
236 LBSLOG2(ELogP3, "LookupFsm session=%d", aSessionId.SessionNum()); |
|
237 |
|
238 // Standard sessions always use the standard state machines. |
|
239 TInt index = iFsmArray.Find(aSessionId, IsSessionIdEqual); |
|
240 if (index >= 0) |
|
241 { |
|
242 LBSLOG(ELogP3, "LookupFsm: Existing standard FSM found"); |
|
243 return iFsmArray[index]; |
|
244 } |
|
245 else |
|
246 { |
|
247 LBSLOG(ELogP3, "LookupFsm: No standard FSM found"); |
|
248 return NULL; |
|
249 } |
|
250 } |
|
251 |
|
252 /** Get a new state machine to use for a new request. |
|
253 |
|
254 The state machine can either be re-using an existing FSM, |
|
255 or allocating a new one from the heap or, for emergencies one thats was prepared earlier is used. |
|
256 */ |
|
257 CLbsPrivLocFsm* CPrivacyAndLocationHandler::GetNewFsm( |
|
258 const TLbsNetSessionIdInt& aSessionId, |
|
259 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
260 TBool aEmergency) |
|
261 { |
|
262 LBSLOG2(ELogP3, "LookupFsm session=%d", aSessionId.SessionNum()); |
|
263 |
|
264 CLbsPrivLocFsm* fsm(NULL); |
|
265 |
|
266 // If this is an emergency request, use the emergency FSM |
|
267 // Note, we only have to support ONE emergency at a time |
|
268 // this implies that only one Protcol module may deal with emergencies |
|
269 // So we do NOT support TWO emergencies .. one from each of the PMs |
|
270 // Note: only MT-LR or NI-LR requests can be emergency requests. |
|
271 if (aEmergency |
|
272 && (aSessionType == MLbsNetworkProtocolObserver::EServiceMobileTerminated |
|
273 || aSessionType == MLbsNetworkProtocolObserver::EServiceNetworkInduced)) |
|
274 { |
|
275 TInt index = iFsmArray.Find(iEmergencyFsm); |
|
276 if (index >= 0) |
|
277 { |
|
278 iFsmArray.Remove(index); |
|
279 iNumActiveSessions--; |
|
280 } |
|
281 // clean out Fsm |
|
282 iEmergencyFsm->RefPosProcessed() = EFalse; |
|
283 iEmergencyFsm->LocReqReceived() = EFalse; |
|
284 iEmergencyFsm->LocationFixReceived()= EFalse; |
|
285 iEmergencyFsm->TapMode() = EFalse; |
|
286 iEmergencyFsm->WasPrivacyResponseReceivedStateExited() = EFalse; |
|
287 iEmergencyFsm->NetSessionId()= aSessionId; |
|
288 fsm = iEmergencyFsm; |
|
289 } |
|
290 else |
|
291 { |
|
292 if (iNumActiveSessions <= iMaxNumSessions) |
|
293 { |
|
294 // Create a new session to handle this privacy request |
|
295 LBSLOG2(ELogP3, "Creating FSM for new standard request %d",aSessionId.SessionNum()); |
|
296 TRAPD(err, fsm = CLbsPrivLocFsm::NewL(*this, aSessionId)); |
|
297 if (err != KErrNone) |
|
298 { |
|
299 LBSLOG_ERR2(ELogP3, "Failed to create new FSM, error code : %d", err); |
|
300 } |
|
301 } |
|
302 else |
|
303 { |
|
304 LBSLOG_ERR3(ELogP3, "Session start rejected! iNumActiveSessions=%d > iMaxNumSessions=%d", iNumActiveSessions, iMaxNumSessions); |
|
305 } |
|
306 } |
|
307 |
|
308 if (fsm) |
|
309 { |
|
310 // Add the state machine to the buffer. |
|
311 iFsmArray.Append(fsm); |
|
312 |
|
313 iNumActiveSessions++; // conceptually, a session starts when a Fsm is created for it |
|
314 |
|
315 } |
|
316 |
|
317 return fsm; |
|
318 } |
|
319 |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // CPrivacyAndLocationHandler::PrivacyHandler |
|
323 // Description: Return a pointer to the privacy handler implementation |
|
324 // (controller or notifier). |
|
325 // ----------------------------------------------------------------------------- |
|
326 // |
|
327 CPrivacyHandler* CPrivacyAndLocationHandler::PrivacyHandler() |
|
328 { |
|
329 return iPrivacyHandler; |
|
330 } |
|
331 |
|
332 // ----------------------------------------------------------------------------- |
|
333 // CPrivacyAndLocationHandler::MessageSwitch |
|
334 // Description: Return a pointer to the Network Gateway Message Switch |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 CNGMessageSwitch* CPrivacyAndLocationHandler::MessageSwitch() |
|
338 { |
|
339 return iMessageSwitch; |
|
340 } |
|
341 |
|
342 // ----------------------------------------------------------------------------- |
|
343 // CPrivacyAndLocationHandler::LbsAdmin |
|
344 // Description: Return a pointer to the Admin settings database |
|
345 // ----------------------------------------------------------------------------- |
|
346 // |
|
347 CLbsAdmin* CPrivacyAndLocationHandler::LbsAdmin() |
|
348 { |
|
349 return iLbsAdmin; |
|
350 } |
|
351 |
|
352 // ----------------------------------------------------------------------------- |
|
353 // CPrivacyAndLocationHandler::SetServerObserver |
|
354 // Description: Store a pointer to the NRH server which comunicates with the |
|
355 // Privacy Controller. |
|
356 // ----------------------------------------------------------------------------- |
|
357 // |
|
358 void CPrivacyAndLocationHandler::SetServerObserver(MLbsSessionObserver* aNrhServer) |
|
359 { |
|
360 PrivacyHandler()->SetServerObserver(aNrhServer); |
|
361 } |
|
362 |
|
363 // ----------------------------------------------------------------------------- |
|
364 // CPrivacyAndLocationHandler::OnRespondNetworkLocationRequest |
|
365 // Description: Called by the Privacy Handler to report the result of a privacy |
|
366 // check. Handling of the response is delegated to the current state. |
|
367 // ----------------------------------------------------------------------------- |
|
368 // |
|
369 void CPrivacyAndLocationHandler::OnRespondNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId, |
|
370 TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult, |
|
371 TInt aResponseReason) |
|
372 { |
|
373 LBSLOG2(ELogP3, "Received response %d to privacy request", aRequestResult); |
|
374 CLbsPrivLocFsm* fsm = LookupFsm(aRequestId); |
|
375 |
|
376 if (NULL != fsm) |
|
377 { |
|
378 fsm->OnRespondNetworkLocationRequest(aRequestId, aRequestResult, aResponseReason); |
|
379 } |
|
380 else |
|
381 { |
|
382 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
383 } |
|
384 } |
|
385 |
|
386 // ----------------------------------------------------------------------------- |
|
387 // CPrivacyAndLocationHandler::OnCancelNetworkLocationRequest |
|
388 // Description: Called by the Privacy Handler to report that a privacy check |
|
389 // has been rejected. This may occur after it has already been accepted. |
|
390 // Handling of the response is delegated to the current state. |
|
391 // ----------------------------------------------------------------------------- |
|
392 // |
|
393 void CPrivacyAndLocationHandler::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId) |
|
394 { |
|
395 LBSLOG2(ELogP3, "Received cancellation to privacy request %d", aRequestId.SessionNum()); |
|
396 CLbsPrivLocFsm* fsm = LookupFsm(aRequestId); |
|
397 |
|
398 if (NULL != fsm) |
|
399 { |
|
400 fsm->OnCancelNetworkLocationRequest(aRequestId); |
|
401 } |
|
402 else |
|
403 { |
|
404 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
405 } |
|
406 } |
|
407 |
|
408 // ----------------------------------------------------------------------------- |
|
409 // CPrivacyAndLocationHandler::OnMTLRRequest |
|
410 // Description: The Message Switch has forwarded a request to start an MTLR |
|
411 // session. |
|
412 // Handling of the request is delegated to the current state. |
|
413 // ----------------------------------------------------------------------------- |
|
414 // |
|
415 void CPrivacyAndLocationHandler::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId, |
|
416 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
417 TBool aIsEmergency, |
|
418 const TLbsExternalRequestInfo& aExternalRequestInfo, |
|
419 const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy) |
|
420 { |
|
421 LBSLOG2(ELogP3, "Received privacy request with id %d", aSessionId.SessionNum()); |
|
422 CLbsPrivLocFsm* fsm = LookupFsm(aSessionId); |
|
423 |
|
424 if (fsm==NULL) |
|
425 { |
|
426 fsm = GetNewFsm(aSessionId, aSessionType, aIsEmergency); |
|
427 } |
|
428 |
|
429 if (NULL != fsm) |
|
430 { |
|
431 fsm->OnMTLRRequest(aSessionId, |
|
432 aSessionType, |
|
433 aIsEmergency, |
|
434 aExternalRequestInfo, |
|
435 aNetPosRequestPrivacy); |
|
436 } |
|
437 else |
|
438 { |
|
439 // Failed to create a state machine for this request, |
|
440 // so simply reply with a privacy rejection. |
|
441 iMessageSwitch->SendMTLRResponse(aSessionId, |
|
442 TLbsNetworkEnumInt::EPrivacyResponseRejected, |
|
443 KErrGeneral, EFalse); // can't be an emergency cuase we know we have a Fsm for these! |
|
444 } |
|
445 } |
|
446 |
|
447 // ----------------------------------------------------------------------------- |
|
448 // CPrivacyAndLocationHandler::OnSessionComplete |
|
449 // Description: The Message Switch has reported that the session is |
|
450 // over (complete or aborted due to some error). |
|
451 // Handling of the message is delegated to the current state. |
|
452 // ----------------------------------------------------------------------------- |
|
453 // |
|
454 void CPrivacyAndLocationHandler::OnSessionComplete( |
|
455 const TLbsNetSessionIdInt& aSessionId, |
|
456 TInt aReason) |
|
457 { |
|
458 LBSLOG3(ELogP3, "Received Session Complete for id %d, reason %d", aSessionId.SessionNum(), aReason); |
|
459 CLbsPrivLocFsm* fsm = LookupFsm(aSessionId); |
|
460 |
|
461 if (NULL != fsm) |
|
462 { |
|
463 fsm->OnSessionComplete(aSessionId, aReason); |
|
464 |
|
465 // The session complete marks the end of a session. |
|
466 TInt index = iFsmArray.Find(fsm); |
|
467 if (index != KErrNotFound) |
|
468 { |
|
469 |
|
470 if (fsm->SessionType()== TLbsNetworkEnumInt::EServiceSelfLocation) |
|
471 { |
|
472 iMolRFsm = NULL; |
|
473 } |
|
474 else if (fsm->SessionType()== TLbsNetworkEnumInt::EServiceTransmitThirdParty) |
|
475 { |
|
476 iX3pFsm = NULL; |
|
477 } |
|
478 |
|
479 // We should never delete the emergency FSM. |
|
480 iFsmArray.Remove(index); |
|
481 iNumActiveSessions--; |
|
482 |
|
483 if (fsm != iEmergencyFsm) |
|
484 { |
|
485 delete fsm; |
|
486 } |
|
487 } |
|
488 } |
|
489 else |
|
490 { |
|
491 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
492 } |
|
493 } |
|
494 |
|
495 // ----------------------------------------------------------------------------- |
|
496 // CPrivacyAndLocationHandler::OnNetLocRequest |
|
497 // Description: The Message Switch has passed on a request for a position update |
|
498 // Handling of the request is delegated to the current state. |
|
499 // ----------------------------------------------------------------------------- |
|
500 // |
|
501 void CPrivacyAndLocationHandler::OnNetLocRequest( |
|
502 const TLbsNetSessionIdInt& aSessionId, |
|
503 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
504 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
505 TBool aIsEmergency, |
|
506 const TLbsNetPosRequestQualityInt& aQuality) |
|
507 { |
|
508 LBSLOG2(ELogP3, "Received position update request for id %d", aSessionId.SessionNum()); |
|
509 |
|
510 TLbsNetSessionIdInt sessionId; |
|
511 TPositionInfo posInfo; |
|
512 TPosition pos; |
|
513 TTime timeStamp; |
|
514 TInt err; |
|
515 |
|
516 TBool tapMode = EFalse; |
|
517 TInt numMethods = aPosRequestMethod.NumPosMethods(); |
|
518 if (numMethods==1) |
|
519 { |
|
520 TLbsNetPosMethodInt netPosMethod; |
|
521 aPosRequestMethod.GetPosMethod(0,netPosMethod); |
|
522 |
|
523 if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)) |
|
524 { |
|
525 tapMode = ETrue; |
|
526 } |
|
527 } |
|
528 |
|
529 // This filtering used to be in the NG Message Switch, but has been moved |
|
530 // here to get an access to the ref position bus |
|
531 |
|
532 if( (aSessionType == TLbsNetworkEnumInt::EServiceNetworkLocation) && !tapMode) |
|
533 { |
|
534 // A Network-based location request generates a location |
|
535 // request to the network request handler, but there's no point |
|
536 // passing it any further - the AGPS manager & privacy |
|
537 // controller aren't interested. |
|
538 // Simply return the saved reference location |
|
539 err = iMessageSwitch->GetNetworkReferencePosition(aSessionId, posInfo); |
|
540 posInfo.GetPosition(pos); |
|
541 timeStamp = pos.Time(); |
|
542 TLbsNetPosRequestQualityInt dummyQuality; |
|
543 MessageSwitch()->SendNetLocResponse(aSessionId, err, dummyQuality, posInfo, timeStamp, EFalse); |
|
544 } |
|
545 else |
|
546 { |
|
547 // we note that a self locate MoLr session can be implicitly |
|
548 // cancelled by the start of a new session for a new client. |
|
549 // In this case we complete the session before creating a new |
|
550 // fsm for the new client |
|
551 CLbsPrivLocFsm* fsm = LookupFsm(aSessionId); |
|
552 if (!fsm) |
|
553 { |
|
554 // here, we need to create a new fsm |
|
555 // We note that only one self locate MolR (or X3p) is supported |
|
556 // a new one will implicitly cancel any ongoing |
|
557 if(aSessionType == TLbsNetworkEnumInt::EServiceSelfLocation) |
|
558 { |
|
559 if (iMolRFsm) |
|
560 { |
|
561 TInt index = iFsmArray.Find(iMolRFsm); |
|
562 if (index != KErrNotFound) |
|
563 { |
|
564 iFsmArray.Remove(index); |
|
565 iNumActiveSessions--; |
|
566 delete iMolRFsm; |
|
567 iMolRFsm = NULL; |
|
568 } |
|
569 } |
|
570 |
|
571 } |
|
572 else if(aSessionType == TLbsNetworkEnumInt::EServiceTransmitThirdParty) |
|
573 { |
|
574 if (iX3pFsm) |
|
575 { |
|
576 TInt index = iFsmArray.Find(iX3pFsm); |
|
577 if (index != KErrNotFound) |
|
578 { |
|
579 iFsmArray.Remove(index); |
|
580 iNumActiveSessions--; |
|
581 delete iX3pFsm; |
|
582 iX3pFsm = NULL; |
|
583 } |
|
584 } |
|
585 } |
|
586 |
|
587 fsm = GetNewFsm(aSessionId, aSessionType, aIsEmergency); |
|
588 } |
|
589 |
|
590 if (NULL != fsm) |
|
591 { |
|
592 if(aSessionType == TLbsNetworkEnumInt::EServiceSelfLocation) |
|
593 { |
|
594 iMolRFsm = fsm; |
|
595 } |
|
596 else if(aSessionType == TLbsNetworkEnumInt::EServiceTransmitThirdParty) |
|
597 { |
|
598 iX3pFsm = fsm; |
|
599 } |
|
600 |
|
601 fsm->OnNetLocRequest(aSessionId, |
|
602 aPosRequestMethod, |
|
603 aSessionType, |
|
604 aIsEmergency, |
|
605 aQuality); |
|
606 } |
|
607 else |
|
608 { |
|
609 // TODO: Return a dummy loc response with error code? |
|
610 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
611 } |
|
612 } |
|
613 } |
|
614 |
|
615 /** Called when a reference position arrives from the network. |
|
616 */ |
|
617 void CPrivacyAndLocationHandler::OnNetLocReferenceUpdate( |
|
618 const TLbsNetSessionIdInt& aSessionId, |
|
619 const TPositionInfoBase& aPosInfo) |
|
620 { |
|
621 LBSLOG2(ELogP3, "Received reference position update for id %d", aSessionId.SessionNum()); |
|
622 CLbsPrivLocFsm* fsm = LookupFsm(aSessionId); |
|
623 |
|
624 if (NULL != fsm) |
|
625 { |
|
626 fsm->OnNetLocReferenceUpdate(aSessionId, aPosInfo); |
|
627 } |
|
628 else |
|
629 { |
|
630 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
631 } |
|
632 } |
|
633 |
|
634 /** Callend when a final location arrives from the network. |
|
635 */ |
|
636 void CPrivacyAndLocationHandler::OnNetLocFinalUpdate( |
|
637 const TLbsNetSessionIdInt& aSessionId, |
|
638 const TPositionInfoBase& aPosInfo) |
|
639 { |
|
640 LBSLOG2(ELogP3, "Received final network position update for id %d", aSessionId.SessionNum()); |
|
641 CLbsPrivLocFsm* fsm = LookupFsm(aSessionId); |
|
642 |
|
643 if (NULL != fsm) |
|
644 { |
|
645 fsm->OnNetLocFinalUpdate(aSessionId, aPosInfo); |
|
646 } |
|
647 else |
|
648 { |
|
649 LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id"); |
|
650 } |
|
651 } |
|
652 |
|
653 /** Callback when a GPS position update arrives from AGPS manager. |
|
654 */ |
|
655 void CPrivacyAndLocationHandler::OnAgpsPositionUpdate( |
|
656 TInt aReason, |
|
657 const TPositionExtendedSatelliteInfo& aPosInfo, |
|
658 const TTime& aTimeStamp) |
|
659 { |
|
660 // Broadcast the update to all state machines. |
|
661 const TInt count = iFsmArray.Count(); |
|
662 for (TInt i = 0; i < count; i++) |
|
663 { |
|
664 iFsmArray[i]->OnAgpsPositionUpdate(aReason, aPosInfo, aTimeStamp); |
|
665 } |
|
666 } |
|
667 |
|
668 /** Callback when a GPS measurement results update arrives from AGPS manager. |
|
669 */ |
|
670 void CPrivacyAndLocationHandler::OnAgpsMeasurementUpdate( |
|
671 TInt aReason, |
|
672 const TPositionGpsMeasurementInfo& aPosInfo, |
|
673 const TTime& aTimeStamp) |
|
674 { |
|
675 // Broadcast the update to all state machines |
|
676 const TInt count = iFsmArray.Count(); |
|
677 for (TInt i = 0; i < count; i++) |
|
678 { |
|
679 iFsmArray[i]->OnAgpsMeasurementUpdate(aReason, aPosInfo, aTimeStamp); |
|
680 } |
|
681 } |
|
682 |
|
683 /** |
|
684 */ |
|
685 CAgpsInterfaceHandler* CPrivacyAndLocationHandler::AgpsHandler() |
|
686 { |
|
687 return iAgpsInterface; |
|
688 } |
|
689 |
|
690 // ----------------------------------------------------------------------------- |
|
691 // CPrivacyAndLocationHandler::DeviceGpsModeCaps |
|
692 // Description: Return the device mode capabilities |
|
693 // ----------------------------------------------------------------------------- |
|
694 // |
|
695 TPositionModuleInfoExtended::TDeviceGpsModeCapabilities CPrivacyAndLocationHandler::DeviceGpsModeCaps() |
|
696 { |
|
697 return iDeviceGpsModeCaps; |
|
698 } |
|
699 |
|
700 // ----------------------------------------------------------------------------- |
|
701 // CPrivacyAndLocationHandler::BehaviourMode |
|
702 // Description: Return the behaviour mode setting |
|
703 // ----------------------------------------------------------------------------- |
|
704 // |
|
705 CLbsAdmin::TLbsBehaviourMode CPrivacyAndLocationHandler::BehaviourMode() |
|
706 { |
|
707 return iLbsBehaviourMode; |
|
708 } |
|
709 |
|
710 RLbsNetworkRegistrationStatus& CPrivacyAndLocationHandler::NetworkRegistrationStatus() |
|
711 { |
|
712 return iNetRegStatus; |
|
713 } |
|
714 |
|
715 // increments the P&S key tracking mobile terminated positioning requests |
|
716 void CPrivacyAndLocationHandler::IncrementPositioningStatus() |
|
717 { |
|
718 TInt count; |
|
719 RProperty::Get(iPosStatusCategory, KLbsNiPositioningStatusKey, count); |
|
720 RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, count+1); |
|
721 } |
|
722 |
|
723 // decrements the P&S key tracking mobile terminated positioning requests |
|
724 // if location management is supported. In the alternative architecture, |
|
725 // the NRH is not aware of the positioning session's progress, but is |
|
726 // transient. Therefore the positioning status is set to zero in the |
|
727 // class destructor. |
|
728 void CPrivacyAndLocationHandler::DecrementPositioningStatus() |
|
729 { |
|
730 if (iLocationManagementSupported) |
|
731 { |
|
732 TInt count; |
|
733 RProperty::Get(iPosStatusCategory, KLbsNiPositioningStatusKey, count); |
|
734 if(count>0) |
|
735 { |
|
736 RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, count-1); |
|
737 } |
|
738 else |
|
739 { |
|
740 LBSLOG_ERR(ELogP3, "CPrivacyAndLocationHandler::DecrementPositioningStatus() - Incorrect Positioning Status count\n"); |
|
741 } |
|
742 } |
|
743 } |
|
744 |
|
745 |
|
746 /** |
|
747 */ |
|
748 MX3pStatusHandler& CPrivacyAndLocationHandler::X3pStatusHandler() |
|
749 { |
|
750 return *iAgpsInterface; |
|
751 } |
|
752 |
|
753 /** Returns ETrue if KLbsSpecialFeatureIntermediateFutileUpdate is on. |
|
754 @return ETrue if the special feature is on, EFalse otherwise. |
|
755 */ |
|
756 TBool CPrivacyAndLocationHandler::IsSpecialFeatureIntermediateFutileUpdateOn() |
|
757 { |
|
758 return iSpecialFeatureIntermediateFutileUpdate; |
|
759 } |
|
760 |
|
761 // ----------------------------------------------------------------------------- |
|
762 // |
|
763 // ----------------------- Class CLbsPrivLocStateBase -------------------- |
|
764 // |
|
765 // This class is not intended for instantiation. Implemented functions are |
|
766 // those common to multiple derived states |
|
767 // |
|
768 // ----------------------------------------------------------------------------- |
|
769 // |
|
770 |
|
771 // ----------------------------------------------------------------------------- |
|
772 // CLbsPrivLocStateBase::OnCancelNetworkLocationRequest |
|
773 // Description: Pass on a received privacy request cancel to the network gateway, |
|
774 // if it relates to the current session. |
|
775 // This behaviour is common to states EStateWaitLocationRequest, |
|
776 // EStateWaitLocationUpdate and EStateWaitPrivacyResponse. |
|
777 // Other states ignore the event. |
|
778 // ----------------------------------------------------------------------------- |
|
779 // |
|
780 void CLbsPrivLocStateBase::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aSessionId) |
|
781 { |
|
782 /* Ignore the cancel if this is an emergency request */ |
|
783 if(!iFsm->IsEmergency()) |
|
784 { |
|
785 // Also ignore it if the cancel doesn't relate to this session. |
|
786 if(aSessionId == iFsm->SessionId()) |
|
787 { |
|
788 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrCancel); |
|
789 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId); |
|
790 } |
|
791 } |
|
792 } |
|
793 |
|
794 // ----------------------------------------------------------------------------- |
|
795 // CLbsPrivLocStateBase::OnEntry |
|
796 // Description: Handles initialisation actions which are common to multiple states. |
|
797 // ----------------------------------------------------------------------------- |
|
798 // |
|
799 void CLbsPrivLocStateBase::OnEntry(const TPrivLocCommonParams& /* aStateParams */) |
|
800 { |
|
801 // Exit reason should always be explicitly set by a state, |
|
802 // otherwise OnExit() will panic |
|
803 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitReasonNone, KErrNone); |
|
804 } |
|
805 |
|
806 |
|
807 // ----------------------------------------------------------------------------- |
|
808 // CLbsPrivLocStateBase::OnExit |
|
809 // Description: Handles exit actions which are common to multiple states. |
|
810 // Any exit reason not handled here is delegated to the current state. |
|
811 // ----------------------------------------------------------------------------- |
|
812 // |
|
813 TBool CLbsPrivLocStateBase::OnExit() |
|
814 { |
|
815 TBool consumed = ETrue; |
|
816 switch(iFsm->iExitData.iExitReason) |
|
817 { |
|
818 case TPrivLocStateExitData::EExitSessionComplete: |
|
819 { |
|
820 // Tell the AGPS interface handle this location request has finished. |
|
821 AgpsInterface()->StopPositioning(iFsm->SessionId()); |
|
822 |
|
823 // Tell the privacy controller this session is finished. |
|
824 PrivacyHandler()->ProcessRequestComplete(iFsm->SessionId(), |
|
825 iFsm->ExitData().iExitInfo); |
|
826 break; |
|
827 } |
|
828 |
|
829 case TPrivLocStateExitData::EExitCancelledByPrivacyController: |
|
830 { |
|
831 // Send a cancel to the network gateway |
|
832 TPositionInfo dummyPosInfo; |
|
833 TTime dummyTime; |
|
834 TLbsNetPosRequestQualityInt dummyQuality; |
|
835 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
836 iFsm->ExitData().iExitInfo, |
|
837 dummyQuality, |
|
838 dummyPosInfo, |
|
839 dummyTime, |
|
840 iFsm->IsEmergency()); |
|
841 } |
|
842 break; |
|
843 |
|
844 case TPrivLocStateExitData::EExitLocReqReceived: |
|
845 // No action required - request is issued on entry to next state. |
|
846 case TPrivLocStateExitData::EExitPrivacyRequestReceived: |
|
847 // No action required, state moves to waiting for loc request. |
|
848 { |
|
849 consumed = ETrue; |
|
850 break; |
|
851 } |
|
852 |
|
853 default: |
|
854 { |
|
855 // Don't know what to do with it. |
|
856 consumed = EFalse; |
|
857 break; |
|
858 } |
|
859 } |
|
860 return(consumed); |
|
861 } |
|
862 |
|
863 // ----------------------------------------------------------------------------- |
|
864 // CLbsPrivLocStateBase::HandleLocRequest |
|
865 // Description: Common handling of a location request received while the |
|
866 // Privacy and Location Handler is dealing with a session. |
|
867 // |
|
868 // If the session type is anything but MTLR, then it is processed, otherwise |
|
869 // a privacy request is generated |
|
870 // ----------------------------------------------------------------------------- |
|
871 // |
|
872 void CLbsPrivLocStateBase::HandleLocRequest(const TLbsNetSessionIdInt& aSessionId, |
|
873 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
874 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
875 TBool aIsEmergency, |
|
876 const TLbsNetPosRequestQualityInt& aQuality) |
|
877 { |
|
878 // MTLR. |
|
879 if (aSessionType == TLbsNetworkEnumInt::EServiceMobileTerminated) |
|
880 { |
|
881 // An MTLR with out a prior privacy request is not supported, report error via |
|
882 // RespondLocationRequest(dummy position). |
|
883 TPositionInfo dummyPosInfo; |
|
884 TTime dummyTime; |
|
885 TLbsNetPosRequestQualityInt dummyQuality; |
|
886 |
|
887 MessageSwitch()->SendNetLocResponse(aSessionId, |
|
888 KErrNotSupported, |
|
889 dummyQuality, |
|
890 dummyPosInfo, |
|
891 dummyTime, aIsEmergency); |
|
892 } |
|
893 |
|
894 // Network Induced. |
|
895 else if (aSessionType == TLbsNetworkEnumInt::EServiceNetworkInduced) |
|
896 { |
|
897 // If a request for a position update has been received without |
|
898 // a privacy request, then there's nothing to say how the user |
|
899 // should be informed or what do do if there is no response. |
|
900 // The safest thing is to get the user to confirm (verify) |
|
901 // the request, and in the absence of confirmation to reject the |
|
902 // request. For emergency requests we notify and accept. |
|
903 |
|
904 // Store the loc req. |
|
905 iFsm->LocReqReceived() = ETrue; |
|
906 |
|
907 iFsm->IsEmergency() = aIsEmergency; |
|
908 iFsm->NetRequestQuality() = aQuality; |
|
909 iFsm->PosRequestMethod() = aPosRequestMethod; |
|
910 |
|
911 |
|
912 // The following notification types are chosen based on the emergency and network requests admin status. |
|
913 // |
|
914 // Emergency = On, Admin = Any, gives ENotifyLocationAccepted |
|
915 // Emergency = Off, Admin = On, gives ENotifyLocationAccepted |
|
916 // Emergency = Off, Admin = OnButAlwayVerify, gives ENotifyAndVerifyLocationRejectedIfNoResponse |
|
917 // Emergency = Off, Admin = Off, N/A the notifier or controller will not be called |
|
918 // Emergency = Off, Admin = OffButNotify, gives ENotifyLocationRejected |
|
919 TLbsNetPosRequestPrivacyInt requestPrivacy; |
|
920 |
|
921 requestPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify); |
|
922 requestPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionAllow); |
|
923 |
|
924 // Verifications are rejected after timeout. |
|
925 CLbsAdmin::TExternalLocateService externalLocate(CLbsAdmin::EExternalLocateOff); |
|
926 |
|
927 ReadNetworkInducedAdminSetting(externalLocate); |
|
928 if ((externalLocate == CLbsAdmin::EExternalLocateOnButAlwaysVerify) && (!aIsEmergency)) |
|
929 { |
|
930 requestPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify); |
|
931 requestPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionReject); |
|
932 } |
|
933 |
|
934 // Similarly, default values have to be assigned to the external request info. |
|
935 TLbsExternalRequestInfo requestInfo; |
|
936 _LIT8(KUnknownExternalReqInfoField, ""); |
|
937 requestInfo.SetRequesterId(KUnknownExternalReqInfoField); |
|
938 requestInfo.SetClientName(KUnknownExternalReqInfoField); |
|
939 requestInfo.SetClientExternalId(KUnknownExternalReqInfoField); |
|
940 |
|
941 |
|
942 // Process the privacy request. |
|
943 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone); |
|
944 |
|
945 TPrivLocWaitPrivResponseParams privacyRequestParams(aSessionId, aSessionType, requestInfo, requestPrivacy, aIsEmergency); |
|
946 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitPrivacyResponse, privacyRequestParams); |
|
947 } |
|
948 |
|
949 // All other location requests. |
|
950 else |
|
951 { |
|
952 TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId, |
|
953 aPosRequestMethod, |
|
954 aSessionType, |
|
955 aIsEmergency, |
|
956 aQuality); |
|
957 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, KErrCancel); |
|
958 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams); |
|
959 } |
|
960 } |
|
961 |
|
962 // ----------------------------------------------------------------------------- |
|
963 // CLbsPrivLocStateBase::OnSessionComplete |
|
964 // Description: Common handling of a session complete message received other |
|
965 // than when it is expected as normal session completion. |
|
966 // ----------------------------------------------------------------------------- |
|
967 // |
|
968 void CLbsPrivLocStateBase::OnSessionComplete(const TLbsNetSessionIdInt& aSessionId, |
|
969 TInt aReason) |
|
970 { |
|
971 if(aSessionId == iFsm->SessionId()) |
|
972 { |
|
973 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, aReason); |
|
974 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId); |
|
975 } |
|
976 } |
|
977 |
|
978 /** Called when a reference position arrives from the network. |
|
979 */ |
|
980 void CLbsPrivLocStateBase::OnNetLocReferenceUpdate( |
|
981 const TLbsNetSessionIdInt& /*aSessionId*/ , |
|
982 const TPositionInfoBase& aPosInfo) |
|
983 { |
|
984 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt sessionType = iFsm->SessionType(); |
|
985 __ASSERT_DEBUG((sessionType != MLbsNetworkProtocolObserver::EServiceNone), Panic(ENrhPanicBadParamType)); |
|
986 |
|
987 if( ((sessionType == MLbsNetworkProtocolObserver::EServiceNetworkInduced) || |
|
988 (sessionType == MLbsNetworkProtocolObserver::EServiceMobileTerminated))) |
|
989 { |
|
990 TPositionInfo posInfo = static_cast<const TPositionInfo&>(aPosInfo); |
|
991 |
|
992 // Set the module Id and position mode for the reference position. |
|
993 // These values are not 'real' values, since this position |
|
994 // came directly from the network and not one of the location |
|
995 // managers within LBS. |
|
996 posInfo.SetModuleId(KLbsGpsLocManagerUid); |
|
997 posInfo.SetPositionMode(TPositionModuleInfo::ETechnologyNetwork); |
|
998 posInfo.SetPositionModeReason(EPositionModeReasonNone); |
|
999 posInfo.SetUpdateType(EPositionUpdateGeneral); |
|
1000 |
|
1001 if (!iFsm->RefPosProcessed()) |
|
1002 { |
|
1003 iFsm->RefPosProcessed() = ETrue; |
|
1004 PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), posInfo); |
|
1005 } |
|
1006 |
|
1007 } |
|
1008 } |
|
1009 |
|
1010 /* Timer callback called when the MaxFixTime for a gps location update request has expired. |
|
1011 |
|
1012 The default action is to ignore this callback. Any state interested in it must |
|
1013 implement its own version. |
|
1014 */ |
|
1015 void CLbsPrivLocStateBase::OnTimerEventL(TInt /*aTimerId*/) |
|
1016 { |
|
1017 } |
|
1018 |
|
1019 |
|
1020 // ----------------------------------------------------------------------------- |
|
1021 // CLbsPrivLocStateBase::ReadNetworkInducedAdminSetting |
|
1022 // Description: Determine the external location value from the admin settings for network induced location requests. |
|
1023 // ----------------------------------------------------------------------------- |
|
1024 // |
|
1025 void CLbsPrivLocStateBase::ReadNetworkInducedAdminSetting(CLbsAdmin::TExternalLocateService& aExternalLocateService) |
|
1026 { |
|
1027 CLbsAdmin::TExternalLocateService serviceStatus(CLbsAdmin::EExternalLocateOff); |
|
1028 RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus netRegStatus(RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown); |
|
1029 TInt err = LbsNetworkRegistrationStatus().GetNetworkRegistrationStatus(netRegStatus); |
|
1030 if (err == KErrNone) |
|
1031 { |
|
1032 switch (netRegStatus) |
|
1033 { |
|
1034 case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork: |
|
1035 { |
|
1036 err = LbsAdmin()->Get(KLbsSettingHomeNetworkInducedLocate, serviceStatus); |
|
1037 break; |
|
1038 } |
|
1039 case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork: |
|
1040 case RLbsNetworkRegistrationStatus::ENotRegistered: |
|
1041 { |
|
1042 err = LbsAdmin()->Get(KLbsSettingRoamingNetworkInducedLocate, serviceStatus); |
|
1043 break; |
|
1044 } |
|
1045 case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown: |
|
1046 default: |
|
1047 { |
|
1048 LBSLOG_WARN2(ELogP4, "Unrecognised TLbsNetworkRegistrationStatus (%d), defaulting to EExternalLocateOff", |
|
1049 netRegStatus); |
|
1050 serviceStatus = CLbsAdmin::EExternalLocateOff; |
|
1051 break; |
|
1052 } |
|
1053 } |
|
1054 } |
|
1055 else |
|
1056 { |
|
1057 LBSLOG_WARN2(ELogP4, "Failed to get TExternalLocateService, couldn't read roaming status (err %d), defaulting to EExternalLocateOff", |
|
1058 err); |
|
1059 } |
|
1060 |
|
1061 aExternalLocateService = serviceStatus; |
|
1062 } |
|
1063 |
|
1064 // ----------------------------------------------------------------------------- |
|
1065 // CLbsPrivLocStateBase::CLbsPrivLocStateBase |
|
1066 // Description: Constructor |
|
1067 // ----------------------------------------------------------------------------- |
|
1068 // |
|
1069 CLbsPrivLocStateBase::CLbsPrivLocStateBase(CLbsPrivLocFsm* aFsm) |
|
1070 : iFsm(aFsm) |
|
1071 { |
|
1072 } |
|
1073 // ----------------------------------------------------------------------------- |
|
1074 // CLbsPrivLocStateBase::PrivacyHandler, MessageSwitch, LbsAdmin |
|
1075 // Description: Allows concrete states access to NRH resources passed to |
|
1076 // the FSM |
|
1077 // Returns: pointers. |
|
1078 // ----------------------------------------------------------------------------- |
|
1079 // |
|
1080 CPrivacyHandler* CLbsPrivLocStateBase::PrivacyHandler() |
|
1081 { |
|
1082 return iFsm->PrivLocHandler().PrivacyHandler(); |
|
1083 } |
|
1084 CNGMessageSwitch* CLbsPrivLocStateBase::MessageSwitch() |
|
1085 { |
|
1086 return iFsm->PrivLocHandler().MessageSwitch(); |
|
1087 } |
|
1088 CLbsAdmin* CLbsPrivLocStateBase::LbsAdmin() |
|
1089 { |
|
1090 return iFsm->PrivLocHandler().LbsAdmin(); |
|
1091 } |
|
1092 CAgpsInterfaceHandler* CLbsPrivLocStateBase::AgpsInterface() |
|
1093 { |
|
1094 return iFsm->PrivLocHandler().AgpsHandler(); |
|
1095 } |
|
1096 |
|
1097 |
|
1098 TPositionModuleInfoExtended::TDeviceGpsModeCapabilities CLbsPrivLocStateBase::DeviceGpsModeCaps() |
|
1099 { |
|
1100 return iFsm->PrivLocHandler().DeviceGpsModeCaps(); |
|
1101 } |
|
1102 |
|
1103 CLbsAdmin::TLbsBehaviourMode CLbsPrivLocStateBase::BehaviourMode() |
|
1104 { |
|
1105 return iFsm->PrivLocHandler().BehaviourMode(); |
|
1106 } |
|
1107 |
|
1108 RLbsNetworkRegistrationStatus& CLbsPrivLocStateBase::LbsNetworkRegistrationStatus() |
|
1109 { |
|
1110 return iFsm->PrivLocHandler().NetworkRegistrationStatus(); |
|
1111 } |
|
1112 |
|
1113 /* |
|
1114 * increments the network initiated positioning status count |
|
1115 * and remembers that it has done |
|
1116 */ |
|
1117 void CLbsPrivLocStateBase::IncrementPositioningStatus() |
|
1118 { |
|
1119 iFsm->PrivLocHandler().IncrementPositioningStatus(); |
|
1120 iFsm->WasPositioningStatusIncremented() = ETrue; |
|
1121 } |
|
1122 |
|
1123 |
|
1124 // ----------------------------------------------------------------------------- |
|
1125 // |
|
1126 // ----------------------- Class CLbsPrivLocIdleState -------------------- |
|
1127 // |
|
1128 // Implements the Idle state of the Privacy and Location Request Handler |
|
1129 // |
|
1130 // ----------------------------------------------------------------------------- |
|
1131 // |
|
1132 |
|
1133 // ----------------------------------------------------------------------------- |
|
1134 // CLbsPrivLocIdleState::NewL |
|
1135 // Description: CLbsPrivLocIdleState static constructor |
|
1136 // ----------------------------------------------------------------------------- |
|
1137 // |
|
1138 CLbsPrivLocIdleState* CLbsPrivLocIdleState::NewL(CLbsPrivLocFsm* aFsm) |
|
1139 { |
|
1140 return new (ELeave) CLbsPrivLocIdleState(aFsm); |
|
1141 } |
|
1142 |
|
1143 // ----------------------------------------------------------------------------- |
|
1144 // CLbsPrivLocIdleState::CLbsPrivLocIdleState |
|
1145 // Description: CLbsPrivLocIdleState constructor. |
|
1146 // ----------------------------------------------------------------------------- |
|
1147 // |
|
1148 CLbsPrivLocIdleState::CLbsPrivLocIdleState(CLbsPrivLocFsm* aFsm) |
|
1149 : CLbsPrivLocStateBase(aFsm) |
|
1150 { |
|
1151 } |
|
1152 |
|
1153 // ----------------------------------------------------------------------------- |
|
1154 // CLbsPrivLocIdleState::OnEntry |
|
1155 // Description: Carries out tasks required on entry to the state. |
|
1156 // ----------------------------------------------------------------------------- |
|
1157 // |
|
1158 void CLbsPrivLocIdleState::OnEntry(const TPrivLocCommonParams& aStateParams) |
|
1159 { |
|
1160 CLbsPrivLocStateBase::OnEntry(aStateParams); |
|
1161 } |
|
1162 |
|
1163 // ----------------------------------------------------------------------------- |
|
1164 // CLbsPrivLocIdleState::OnExit |
|
1165 // Description: Carries out tasks required on exit from the state. |
|
1166 // Panics if the exit reason is not handled by the base state exit |
|
1167 // ----------------------------------------------------------------------------- |
|
1168 // |
|
1169 TBool CLbsPrivLocIdleState::OnExit() |
|
1170 { |
|
1171 TBool consumed = CLbsPrivLocStateBase::OnExit(); |
|
1172 // If the exit reason wasn't handled, panic (should only happen in development) |
|
1173 __ASSERT_DEBUG(consumed, Panic(ENrhPanicIdleUnknownExitReason)); |
|
1174 |
|
1175 return(consumed); |
|
1176 } |
|
1177 |
|
1178 // ----------------------------------------------------------------------------- |
|
1179 // CLbsPrivLocIdleState::OnNetLocRequest |
|
1180 // Description: The Message Switch has forwarded a request for a control |
|
1181 // measurement. |
|
1182 // If the session type is anything but MTLR, then it is processed, otherwise |
|
1183 // a privacy request is generated |
|
1184 // ----------------------------------------------------------------------------- |
|
1185 // |
|
1186 void CLbsPrivLocIdleState::OnNetLocRequest( |
|
1187 const TLbsNetSessionIdInt& aSessionId, |
|
1188 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
1189 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
1190 TBool aIsEmergency, |
|
1191 const TLbsNetPosRequestQualityInt& aQuality) |
|
1192 { |
|
1193 iFsm->SessionType() = aSessionType; |
|
1194 if(iFsm->WasPrivacyResponseReceivedStateExited()) |
|
1195 { |
|
1196 // The request relates to a rejected privacy request |
|
1197 // or a request for this session which has already been answered. |
|
1198 // In either case, it should be refused. The message is sent to the |
|
1199 // network gateway as a part of exit from the state, but we want to |
|
1200 // remain in Idle state. |
|
1201 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrAccessDenied); |
|
1202 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId); |
|
1203 } |
|
1204 else |
|
1205 { |
|
1206 TInt numMethods = aPosRequestMethod.NumPosMethods(); |
|
1207 if (numMethods==1) |
|
1208 { |
|
1209 TLbsNetPosMethodInt netPosMethod; |
|
1210 aPosRequestMethod.GetPosMethod(0,netPosMethod); |
|
1211 |
|
1212 if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)) |
|
1213 { |
|
1214 iFsm->TapMode() = ETrue; |
|
1215 } |
|
1216 } |
|
1217 |
|
1218 |
|
1219 if ((aSessionType != MLbsNetworkProtocolObserver::EServiceMobileTerminated) && |
|
1220 (aSessionType != MLbsNetworkProtocolObserver::EServiceNetworkInduced)) |
|
1221 { |
|
1222 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone); |
|
1223 TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId, |
|
1224 aPosRequestMethod, |
|
1225 aSessionType, |
|
1226 aIsEmergency, |
|
1227 aQuality); |
|
1228 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams); |
|
1229 } |
|
1230 else |
|
1231 { |
|
1232 // It's a request for a different session. Need to find out what to do with it. |
|
1233 HandleLocRequest(aSessionId, aPosRequestMethod, |
|
1234 aSessionType,aIsEmergency, |
|
1235 aQuality); |
|
1236 } |
|
1237 } |
|
1238 } |
|
1239 |
|
1240 // ----------------------------------------------------------------------------- |
|
1241 // CLbsPrivLocIdleState::OnMTLRRequest |
|
1242 // Description: The Message Switch has forwarded a request for a location update |
|
1243 // (a privacy request) |
|
1244 // ----------------------------------------------------------------------------- |
|
1245 // |
|
1246 void CLbsPrivLocIdleState::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId, |
|
1247 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
1248 TBool aIsEmergency, |
|
1249 const TLbsExternalRequestInfo& aExternalRequestInfo, |
|
1250 const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy) |
|
1251 { |
|
1252 iFsm->SessionType() = aSessionType; |
|
1253 iFsm->ExternalRequestType() = aExternalRequestInfo.RequestType(); |
|
1254 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitPrivacyRequestReceived, KErrNone); |
|
1255 TPrivLocWaitPrivResponseParams privacyRequestParams( aSessionId, |
|
1256 aSessionType, |
|
1257 aExternalRequestInfo, |
|
1258 aNetPosRequestPrivacy, |
|
1259 aIsEmergency); |
|
1260 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitPrivacyResponse, privacyRequestParams); |
|
1261 } |
|
1262 |
|
1263 /** Called when a reference position arrives from the network. |
|
1264 * |
|
1265 */ |
|
1266 void CLbsPrivLocIdleState::OnNetLocReferenceUpdate( |
|
1267 const TLbsNetSessionIdInt& /*aSessionId*/, |
|
1268 const TPositionInfoBase& /* aPosInfo */) |
|
1269 { |
|
1270 // note that the reference postion is stored by the message switch |
|
1271 // so here we don't need to save it again! |
|
1272 } |
|
1273 |
|
1274 // ----------------------------------------------------------------------------- |
|
1275 // |
|
1276 // ----------------------- Class CLbsPrivLocWaitPrivRespState -------------------- |
|
1277 // |
|
1278 // Implements the Idle state of the Privacy and Location Request Handler |
|
1279 // |
|
1280 // ----------------------------------------------------------------------------- |
|
1281 // |
|
1282 |
|
1283 // ----------------------------------------------------------------------------- |
|
1284 // CLbsPrivLocWaitPrivRespState::NewL |
|
1285 // Description: CLbsPrivLocIdleState static constructor |
|
1286 // ----------------------------------------------------------------------------- |
|
1287 // |
|
1288 CLbsPrivLocWaitPrivRespState* CLbsPrivLocWaitPrivRespState::NewL(CLbsPrivLocFsm* aFsm) |
|
1289 { |
|
1290 return new (ELeave) CLbsPrivLocWaitPrivRespState(aFsm); |
|
1291 } |
|
1292 |
|
1293 // ----------------------------------------------------------------------------- |
|
1294 // CLbsPrivLocWaitPrivRespState::CLbsPrivLocWaitPrivRespState |
|
1295 // Description: CLbsPrivLocWaitPrivRespState constructor. |
|
1296 // ----------------------------------------------------------------------------- |
|
1297 // |
|
1298 CLbsPrivLocWaitPrivRespState::CLbsPrivLocWaitPrivRespState(CLbsPrivLocFsm* aFsm) |
|
1299 : CLbsPrivLocStateBase(aFsm) |
|
1300 { |
|
1301 } |
|
1302 |
|
1303 // ----------------------------------------------------------------------------- |
|
1304 // CLbsPrivLocWaitPrivRespState::OnEntry |
|
1305 // Description: Actions performed when the state is entered. |
|
1306 // Unpack the parameters and issue the privacy request. |
|
1307 // ----------------------------------------------------------------------------- |
|
1308 // |
|
1309 void CLbsPrivLocWaitPrivRespState::OnEntry(const TPrivLocCommonParams& aStateParams) |
|
1310 { |
|
1311 CLbsPrivLocStateBase::OnEntry(aStateParams); |
|
1312 const TPrivLocWaitPrivResponseParams& params = TPrivLocWaitPrivResponseParams::Cast(const_cast<TPrivLocCommonParams&>(aStateParams)); |
|
1313 iFsm->SessionType() = params.iSessionType; |
|
1314 iFsm->IsEmergency() = params.iIsEmergency; |
|
1315 |
|
1316 PrivacyHandler()->ProcessNetworkLocationRequest(iFsm->SessionId(), |
|
1317 iFsm->SessionType(), |
|
1318 params.iExternalRequestInfo, |
|
1319 params.iNetPosRequestPrivacy, |
|
1320 iFsm->IsEmergency()); |
|
1321 } |
|
1322 |
|
1323 // ----------------------------------------------------------------------------- |
|
1324 // CLbsPrivLocWaitPrivRespState::OnExit |
|
1325 // Description: Actions performed on leaving the state. |
|
1326 // ----------------------------------------------------------------------------- |
|
1327 // |
|
1328 TBool CLbsPrivLocWaitPrivRespState::OnExit() |
|
1329 { |
|
1330 TInt consumed = EFalse; |
|
1331 switch(iFsm->ExitData().iExitReason) |
|
1332 { |
|
1333 case TPrivLocStateExitData::EExitPrivacyResponseReceived: |
|
1334 { |
|
1335 // Remember that we exited the privacy response received state |
|
1336 // so that we can deny the network location requests in the idle staet. |
|
1337 |
|
1338 iFsm->WasPrivacyResponseReceivedStateExited() = ETrue; |
|
1339 |
|
1340 |
|
1341 // For the NI case a Reference position may have arrived by now |
|
1342 // So we must pass this onto the privacy handler. |
|
1343 |
|
1344 if (iFsm->SessionType() == MLbsNetworkProtocolObserver::EServiceNetworkInduced) |
|
1345 { |
|
1346 if (iFsm->PrivacyResponse() == CLbsNetworkProtocolBase::EPrivacyResponseAccepted) |
|
1347 { |
|
1348 TPositionInfo posInfo; |
|
1349 TInt err = MessageSwitch()->GetNetworkReferencePosition(iFsm->SessionId(), posInfo); |
|
1350 if (KErrNone == err) |
|
1351 { |
|
1352 if (!iFsm->RefPosProcessed()) |
|
1353 { |
|
1354 iFsm->RefPosProcessed() = ETrue; |
|
1355 PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), posInfo); |
|
1356 } |
|
1357 |
|
1358 } |
|
1359 |
|
1360 } |
|
1361 } |
|
1362 |
|
1363 // For MtLrs the Protocol module should not |
|
1364 // send a REF position until after we have sent the Priv response to the PM |
|
1365 |
|
1366 // Inform network of the privacy response for normal privacy requests. |
|
1367 if (iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated) |
|
1368 { |
|
1369 MessageSwitch()->SendMTLRResponse(iFsm->SessionId(), iFsm->PrivacyResponse(), iFsm->PrivacyResponseReason(), iFsm->IsEmergency()); |
|
1370 } |
|
1371 |
|
1372 // Inform network of a rejected privacy response via a "RespondLocationRequest" for faked privacy requests (generated internaly). |
|
1373 else if ((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceNetworkInduced) && (iFsm->PrivacyResponse() == TLbsNetworkEnumInt::EPrivacyResponseRejected)) |
|
1374 { |
|
1375 // The faked privacy request was rejected, so reject the location request. |
|
1376 TPositionInfo dummyPosInfo; |
|
1377 TTime dummyTime; |
|
1378 TLbsNetPosRequestQualityInt dummyQuality; |
|
1379 |
|
1380 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1381 KErrAccessDenied, |
|
1382 dummyQuality, |
|
1383 dummyPosInfo, |
|
1384 dummyTime, |
|
1385 iFsm->IsEmergency()); |
|
1386 } |
|
1387 |
|
1388 consumed = ETrue; |
|
1389 break; |
|
1390 } |
|
1391 |
|
1392 case TPrivLocStateExitData::EExitCancelledByPrivacyController: |
|
1393 { |
|
1394 // Send a cancel to the network gateway |
|
1395 iFsm->PrivacyResponse() = TLbsNetworkEnumInt::EPrivacyResponseRejected; |
|
1396 iFsm->PrivacyResponseReason() = KErrCancel; |
|
1397 MessageSwitch()->SendMTLRResponse(iFsm->SessionId(), iFsm->PrivacyResponse(), iFsm->PrivacyResponseReason(), iFsm->IsEmergency()); |
|
1398 consumed = ETrue; |
|
1399 } |
|
1400 break; |
|
1401 |
|
1402 default: |
|
1403 { |
|
1404 consumed = CLbsPrivLocStateBase::OnExit(); |
|
1405 // If the exit reason wasn't handled, panic (should only happen in development) |
|
1406 __ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitPrivRespUnknownExitReason)); |
|
1407 break; |
|
1408 } |
|
1409 } |
|
1410 |
|
1411 iFsm->LocReqReceived() = EFalse; |
|
1412 |
|
1413 return(consumed); |
|
1414 } |
|
1415 |
|
1416 // ----------------------------------------------------------------------------- |
|
1417 // CLbsPrivLocWaitPrivRespState::OnRespondNetworkLocationRequest |
|
1418 // Description: Pass on a received privacy response to the network gateway, if |
|
1419 // it relates to the current session. |
|
1420 // ----------------------------------------------------------------------------- |
|
1421 // |
|
1422 void CLbsPrivLocWaitPrivRespState::OnRespondNetworkLocationRequest( |
|
1423 const TLbsNetSessionIdInt& aSessionId, |
|
1424 TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult, |
|
1425 TInt /* aResponseReason*/) |
|
1426 { |
|
1427 |
|
1428 if(aSessionId == iFsm->SessionId()) |
|
1429 { |
|
1430 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitPrivacyResponseReceived, KErrNone); |
|
1431 iFsm->PrivacyResponse() = aRequestResult; |
|
1432 if(iFsm->PrivacyResponse() == TLbsNetworkEnumInt::EPrivacyResponseAccepted) |
|
1433 { |
|
1434 // Tell the AGPS handler that we are going to start a location request soon. |
|
1435 AgpsInterface()->PreStartPositioning(iFsm->SessionId(), iFsm->IsEmergency()); |
|
1436 |
|
1437 // Set the Positioning Status for the UI indicator. |
|
1438 // Not done for silent requests. |
|
1439 if (iFsm->ExternalRequestType() < TLbsExternalRequestInfo::ERequestSingleShotSilent) |
|
1440 { |
|
1441 IncrementPositioningStatus(); |
|
1442 } |
|
1443 |
|
1444 if(iFsm->LocReqReceived()) |
|
1445 { |
|
1446 TPrivLocWaitLocationUpdateParams updateRequestParams(iFsm->SessionId(), |
|
1447 iFsm->PosRequestMethod(), |
|
1448 iFsm->SessionType(), |
|
1449 iFsm->IsEmergency(), |
|
1450 iFsm->NetRequestQuality()); |
|
1451 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams); |
|
1452 } |
|
1453 else |
|
1454 { |
|
1455 TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(), |
|
1456 iFsm->IsEmergency(), |
|
1457 EFalse); |
|
1458 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams); |
|
1459 } |
|
1460 } |
|
1461 else |
|
1462 { |
|
1463 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId); |
|
1464 } |
|
1465 } |
|
1466 } |
|
1467 |
|
1468 // ----------------------------------------------------------------------------- |
|
1469 // CLbsPrivLocWaitPrivRespState::OnNetLocRequest |
|
1470 // Description: The Message Switch has forwarded a request for a control |
|
1471 // measurement. |
|
1472 // If the session Id is the same as the current one, then save the parameters |
|
1473 // so that the request can be issued when privacy is accepted. |
|
1474 // Otherwise (the session Id is different) a cancel is implied and we cancel |
|
1475 // the current session and start another, which may or may not require a new |
|
1476 // privacy query. |
|
1477 // ----------------------------------------------------------------------------- |
|
1478 // |
|
1479 void CLbsPrivLocWaitPrivRespState::OnNetLocRequest( |
|
1480 const TLbsNetSessionIdInt& aSessionId, |
|
1481 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
1482 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
1483 TBool aIsEmergency, |
|
1484 const TLbsNetPosRequestQualityInt& aQuality) |
|
1485 { |
|
1486 TInt numMethods = aPosRequestMethod.NumPosMethods(); |
|
1487 if (numMethods==1) |
|
1488 { |
|
1489 TLbsNetPosMethodInt netPosMethod; |
|
1490 aPosRequestMethod.GetPosMethod(0,netPosMethod); |
|
1491 |
|
1492 if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)) |
|
1493 { |
|
1494 iFsm->TapMode() = ETrue; |
|
1495 } |
|
1496 } |
|
1497 if(aSessionId == iFsm->SessionId() && |
|
1498 aIsEmergency == iFsm->IsEmergency() && |
|
1499 aSessionType == iFsm->SessionType()) |
|
1500 { |
|
1501 iFsm->PosRequestMethod() = aPosRequestMethod; |
|
1502 iFsm->NetRequestQuality() = aQuality; |
|
1503 iFsm->LocReqReceived() = ETrue; |
|
1504 } |
|
1505 else |
|
1506 { |
|
1507 // It's a request for different session. Need to find out what to do with it. |
|
1508 HandleLocRequest(aSessionId,aPosRequestMethod, |
|
1509 aSessionType,aIsEmergency, |
|
1510 aQuality); |
|
1511 } |
|
1512 } |
|
1513 |
|
1514 |
|
1515 void CLbsPrivLocWaitPrivRespState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/, |
|
1516 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, |
|
1517 TBool /*aIsEmergency*/, |
|
1518 const TLbsExternalRequestInfo& /*aExternalRequestInfo*/, |
|
1519 const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/) |
|
1520 { |
|
1521 // this can never happen. If the Fsm is in the WaitPrivRespState then |
|
1522 // any arrival of a MTLR request would start a new session (no implicit cancel!) |
|
1523 // and the OnMTLRRequest()would be directed to that session not this one |
|
1524 __ASSERT_DEBUG(EFalse, Panic(ENrhPanicBadParamType)); |
|
1525 } |
|
1526 |
|
1527 /** Called when a reference position arrives from the network. |
|
1528 * |
|
1529 */ |
|
1530 void CLbsPrivLocWaitPrivRespState::OnNetLocReferenceUpdate( |
|
1531 const TLbsNetSessionIdInt& /*aSessionId*/, |
|
1532 const TPositionInfoBase& /*aPosInfo*/) |
|
1533 { |
|
1534 // note that the reference postion is stored by the message switch |
|
1535 // so here we don't need to save it again! |
|
1536 } |
|
1537 |
|
1538 |
|
1539 // ----------------------------------------------------------------------------- |
|
1540 // |
|
1541 // ----------------------- Class CLbsPrivLocWaitLocUpdateState -------------------- |
|
1542 // |
|
1543 // Implements the Wait For Location Update state of the Privacy and Location |
|
1544 // Request Handler |
|
1545 // |
|
1546 // On entry, issues a location update request then starts a timer and waits for |
|
1547 // a response. |
|
1548 // |
|
1549 // ----------------------------------------------------------------------------- |
|
1550 // |
|
1551 |
|
1552 // ----------------------------------------------------------------------------- |
|
1553 // CLbsPrivLocWaitLocUpdateState::NewL |
|
1554 // Description: CLbsPrivLocWaitLocUpdateState static constructor |
|
1555 // ----------------------------------------------------------------------------- |
|
1556 // |
|
1557 CLbsPrivLocWaitLocUpdateState* CLbsPrivLocWaitLocUpdateState::NewL(CLbsPrivLocFsm* aFsm) |
|
1558 { |
|
1559 CLbsPrivLocWaitLocUpdateState* self; |
|
1560 self = new (ELeave) CLbsPrivLocWaitLocUpdateState(aFsm); |
|
1561 CleanupStack::PushL(self); |
|
1562 self->ConstructL(); |
|
1563 CleanupStack::Pop(self); |
|
1564 return(self); |
|
1565 } |
|
1566 |
|
1567 // ----------------------------------------------------------------------------- |
|
1568 // CLbsPrivLocWaitLocUpdateState::CLbsPrivLocWaitLocUpdateState |
|
1569 // Description: CLbsPrivLocWaitLocUpdateState constructor. |
|
1570 // ----------------------------------------------------------------------------- |
|
1571 // |
|
1572 CLbsPrivLocWaitLocUpdateState::CLbsPrivLocWaitLocUpdateState(CLbsPrivLocFsm* aFsm) |
|
1573 : CLbsPrivLocStateBase(aFsm) |
|
1574 { |
|
1575 } |
|
1576 |
|
1577 // ----------------------------------------------------------------------------- |
|
1578 // CLbsPrivLocWaitLocUpdateState::~CLbsPrivLocWaitLocUpdateState |
|
1579 // Description: CLbsPrivLocWaitLocUpdateState destructor. |
|
1580 // ----------------------------------------------------------------------------- |
|
1581 // |
|
1582 CLbsPrivLocWaitLocUpdateState::~CLbsPrivLocWaitLocUpdateState() |
|
1583 { |
|
1584 } |
|
1585 |
|
1586 // ----------------------------------------------------------------------------- |
|
1587 // CLbsPrivLocIdleState::ConstructL |
|
1588 // Description: CLbsPrivLocIdleState second-phase constructor. |
|
1589 // ----------------------------------------------------------------------------- |
|
1590 // |
|
1591 void CLbsPrivLocWaitLocUpdateState::ConstructL() |
|
1592 { |
|
1593 } |
|
1594 |
|
1595 |
|
1596 // ----------------------------------------------------------------------------- |
|
1597 // CLbsPrivLocWaitLocUpdateState::OnEntry |
|
1598 // Description: Carries out tasks required on entry to the state. |
|
1599 // Issues the location update request and starts a timer. |
|
1600 // ----------------------------------------------------------------------------- |
|
1601 // |
|
1602 void CLbsPrivLocWaitLocUpdateState::OnEntry(const TPrivLocCommonParams& aStateParams) |
|
1603 { |
|
1604 TInt err(KErrNone); |
|
1605 |
|
1606 CLbsPrivLocStateBase::OnEntry(aStateParams); |
|
1607 const TPrivLocWaitLocationUpdateParams& params = TPrivLocWaitLocationUpdateParams::Cast(aStateParams); |
|
1608 iFsm->IsEmergency() = params.iIsEmergency; |
|
1609 iFsm->SessionType() = params.iSessionType; |
|
1610 iFsm->PosRequestMethod() = params.iPosRequestMethod; |
|
1611 |
|
1612 // If the network has not specified a positioning method, get the default |
|
1613 // one from the admin settings. |
|
1614 TLbsNetPosMethodInt netReqMethod; |
|
1615 iFsm->PosRequestMethod().GetPosMethod(0, netReqMethod); |
|
1616 if (iFsm->PosRequestMethod().NumPosMethods() == 1 |
|
1617 && (netReqMethod.PosMode() == TPositionModuleInfo::ETechnologyUnknown)) |
|
1618 { |
|
1619 AgpsInterface()->GetDefaultPosMethod(iFsm->PosRequestMethod()); |
|
1620 } |
|
1621 |
|
1622 // We may use two sources for the required quality for the |
|
1623 // new location request, either: |
|
1624 // 1) The quality from the network (aQuality) |
|
1625 // 2) The quality defined in a quality profile (which profile to |
|
1626 // use depends on the service type, e.g. MT-LR or X3P) |
|
1627 // |
|
1628 // We decide which to use based on the required quality from the network. |
|
1629 // Any invalid/unsupplied parameter is read from the quality profile |
|
1630 // for the ocation request type. |
|
1631 TBool maxFixTimeRequired = params.iQuality.MaxFixTime() == 0; |
|
1632 TBool minVerticalAccuracyRequired = |
|
1633 Math::IsNaN(params.iQuality.MinVerticalAccuracy()); |
|
1634 TBool minHorizontalAccuracyRequired = |
|
1635 Math::IsNaN(params.iQuality.MinHorizontalAccuracy()); |
|
1636 |
|
1637 if (maxFixTimeRequired || minVerticalAccuracyRequired || minHorizontalAccuracyRequired) |
|
1638 { |
|
1639 // Select which LbsAdmin setting to use for the |
|
1640 // quality profile Id based on the type of location |
|
1641 // request. |
|
1642 TLbsAdminSetting adminSetting(KLbsSettingNone); |
|
1643 switch (iFsm->SessionType()) |
|
1644 { |
|
1645 case TLbsNetworkEnumInt::EServiceMobileTerminated: |
|
1646 case TLbsNetworkEnumInt::EServiceNetworkInduced: |
|
1647 { |
|
1648 adminSetting = KLbsSettingQualityProfileExternalLocate; |
|
1649 break; |
|
1650 } |
|
1651 case TLbsNetworkEnumInt::EServiceTransmitThirdParty: |
|
1652 { |
|
1653 adminSetting = KLbsSettingQualityProfileTransmitLocate; |
|
1654 break; |
|
1655 } |
|
1656 case TLbsNetworkEnumInt::EServiceTriggeredMolr: |
|
1657 // SUPL 2.0 "Triggered MOLR" request uses Self Locate Quality Profile |
|
1658 case TLbsNetworkEnumInt::EServiceNetworkLocation: |
|
1659 // This type of request should only get here in the case of a TA MOLR. Treat as Self-Locate |
|
1660 case TLbsNetworkEnumInt::EServiceSelfLocation: |
|
1661 { |
|
1662 adminSetting = KLbsSettingQualityProfileSelfLocate; |
|
1663 break; |
|
1664 } |
|
1665 default: |
|
1666 { |
|
1667 // We must not fail if it is an emergency request |
|
1668 if (!iFsm->IsEmergency()) |
|
1669 { |
|
1670 LBSLOG2(ELogP3, |
|
1671 "Unable to select quality profile for TLbsNetProtocolService (%d), using quality data from network instead.", |
|
1672 iFsm->SessionType()); |
|
1673 __ASSERT_DEBUG(EFalse, Panic(ENrhPanicNoQualityProfile)); |
|
1674 } |
|
1675 else |
|
1676 { |
|
1677 adminSetting = KLbsSettingQualityProfileExternalLocate; |
|
1678 } |
|
1679 } |
|
1680 } |
|
1681 |
|
1682 // Retrieve the Id of the quality profile to use |
|
1683 TLbsQualityProfileId profileId(KLbsNullQualityProfileId); |
|
1684 if (adminSetting != KLbsSettingNone) |
|
1685 { |
|
1686 LbsAdmin()->Get(adminSetting, profileId); |
|
1687 } |
|
1688 |
|
1689 // Retrieve the data for the quality profile |
|
1690 TQualityProfile qualityProfile; |
|
1691 err = LbsQualityProfile::GetQualityProfileById(profileId, qualityProfile); |
|
1692 if (err == KErrNone) |
|
1693 { |
|
1694 // Use the quality data from the quality profile for any missing/invalid data |
|
1695 if(maxFixTimeRequired) |
|
1696 { |
|
1697 iFsm->GpsRequestQuality().SetMaxFixTime(qualityProfile.MaxFixTime()); |
|
1698 } |
|
1699 else |
|
1700 { |
|
1701 iFsm->GpsRequestQuality().SetMaxFixTime(params.iQuality.MaxFixTime()); |
|
1702 } |
|
1703 if(minHorizontalAccuracyRequired) |
|
1704 { |
|
1705 iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(qualityProfile.MinHorizontalAccuracy()); |
|
1706 } |
|
1707 else |
|
1708 { |
|
1709 iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(params.iQuality.MinHorizontalAccuracy()); |
|
1710 } |
|
1711 if(minVerticalAccuracyRequired) |
|
1712 { |
|
1713 iFsm->GpsRequestQuality().SetMinVerticalAccuracy(qualityProfile.MinVerticalAccuracy()); |
|
1714 } |
|
1715 else |
|
1716 { |
|
1717 iFsm->GpsRequestQuality().SetMinVerticalAccuracy(params.iQuality.MinVerticalAccuracy()); |
|
1718 } |
|
1719 } |
|
1720 else |
|
1721 { |
|
1722 // We should not fail if we are emergency |
|
1723 if (!iFsm->IsEmergency()) |
|
1724 { |
|
1725 // We couldn't find the quality profile with the given Id. |
|
1726 // This is an error, so reject the location request. |
|
1727 TPositionInfo dummyPosInfo; |
|
1728 TTime dummyTime; |
|
1729 TLbsNetPosRequestQualityInt dummyQuality; |
|
1730 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1731 KErrAccessDenied, |
|
1732 dummyQuality, |
|
1733 dummyPosInfo, |
|
1734 dummyTime, |
|
1735 iFsm->IsEmergency()); |
|
1736 |
|
1737 // if this location request is the result of a privacy request, |
|
1738 // then notify the privacy handler of the error |
|
1739 if ((params.iSessionType == TLbsNetworkEnumInt::EServiceMobileTerminated) || |
|
1740 (params.iSessionType == TLbsNetworkEnumInt::EServiceNetworkInduced)) |
|
1741 { |
|
1742 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, KErrAccessDenied); |
|
1743 } |
|
1744 else |
|
1745 { |
|
1746 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitBadQualityProfile, KErrNone); |
|
1747 } |
|
1748 |
|
1749 // Whatever the result, this session is finished, so return to idle. |
|
1750 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, iFsm->SessionId()); |
|
1751 return; |
|
1752 } // if (!iIsEmergency) |
|
1753 else |
|
1754 { |
|
1755 // Just set some defaults |
|
1756 TTimeIntervalMicroSeconds timeout(30000000); |
|
1757 iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(50); |
|
1758 iFsm->GpsRequestQuality().SetMinVerticalAccuracy(1000); |
|
1759 iFsm->GpsRequestQuality().SetMaxFixTime(timeout); |
|
1760 } |
|
1761 } |
|
1762 } |
|
1763 else |
|
1764 { |
|
1765 // Use the quality parameters supplied with the request. |
|
1766 iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(params.iQuality.MinHorizontalAccuracy()); |
|
1767 iFsm->GpsRequestQuality().SetMinVerticalAccuracy(params.iQuality.MinVerticalAccuracy()); |
|
1768 iFsm->GpsRequestQuality().SetMaxFixTime(params.iQuality.MaxFixTime()); |
|
1769 } |
|
1770 |
|
1771 |
|
1772 // Check for any existing position updates in case they meet the |
|
1773 // MaxFixAge and quality requirements for this request. |
|
1774 TInt updateReason; |
|
1775 err = AgpsInterface()->GetPosition(updateReason, |
|
1776 iFsm->GpsPosition(), |
|
1777 iFsm->ActualTime()); |
|
1778 if (err == KErrNone) |
|
1779 { |
|
1780 TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(), |
|
1781 iFsm->IsEmergency(), |
|
1782 EFalse, |
|
1783 updateReason); |
|
1784 |
|
1785 // Check the existing update in case it meets the MaxFixAge and quality requirements for this request. |
|
1786 if (params.iQuality.MaxFixAge() > 0) |
|
1787 { |
|
1788 TTime now; |
|
1789 now.UniversalTime(); |
|
1790 TTimeIntervalMicroSeconds age(Max((now.Int64() - iFsm->ActualTime().Int64()), TInt64(0))); |
|
1791 if (updateReason == KErrNone |
|
1792 && (age <= params.iQuality.MaxFixAge()) |
|
1793 && ReceivedFixIsAccurate()) |
|
1794 { |
|
1795 // Accurate update that is within the MaxFixAge time limit, |
|
1796 // so return it straight away. |
|
1797 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, updateReason); |
|
1798 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams); |
|
1799 return; |
|
1800 } |
|
1801 } |
|
1802 |
|
1803 |
|
1804 // Special feature behaviour! |
|
1805 // If the admin setting KLbsSpecialFeatureIntermediateFutileUpdate is on, |
|
1806 // it means that we should check to see if a futile update has happened |
|
1807 // since the first location request of this session. This might happen |
|
1808 // in a hybrid session, if the GPS module sends a futile update when there |
|
1809 // is no outstanding location request in the NRH. E.g. in the gap between |
|
1810 // sending the response for one hybrid loc request and getting the next |
|
1811 // loc request from the network. |
|
1812 // |
|
1813 // Note: This only really applies to hybrid of TA position modes, because |
|
1814 // in TB or autonomous you only have one location request per |
|
1815 // session. |
|
1816 else if (iFsm->IsSpecialFeatureIntermediateFutileUpdateOn()) |
|
1817 { |
|
1818 // If this is the first request for a new sessionId, record the current session id. |
|
1819 // We need to know this for terminal assisted or hybrid requests, in case |
|
1820 // we need to check for a futile update that has happened in the gap between |
|
1821 // one location response and the next location update request. |
|
1822 if (iFsm->LastLocReqSessionId() != iFsm->SessionId()) |
|
1823 { |
|
1824 iFsm->LastLocReqSessionId() = iFsm->SessionId(); |
|
1825 } |
|
1826 else |
|
1827 { |
|
1828 // Before sending the location request, see if a futile update has |
|
1829 // happened since the start of the session (in general only terminal-assisted |
|
1830 // and hybrid requests should have more than one location request |
|
1831 // per session, however the SUPL PM will have more than one for all request modes). |
|
1832 TGpsRequestMode gpsMode = AgpsInterface()->ConvertPosMethodToGpsRequestMode(iFsm->PosRequestMethod()); |
|
1833 if ((updateReason == KPositionCalculationFutile) && |
|
1834 ((gpsMode == EGpsRequestModeTerminalAssisted) || (gpsMode == EGpsRequestModeHybrid))) |
|
1835 { |
|
1836 // Return last measurement straight away. |
|
1837 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, updateReason); |
|
1838 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams); |
|
1839 return; |
|
1840 } |
|
1841 } |
|
1842 } |
|
1843 } |
|
1844 |
|
1845 |
|
1846 // Issue the request and supply pointers to the data to be updated |
|
1847 iFsm->LocationFixReceived() = EFalse; |
|
1848 iFsm->MeasurementInfoReceived() = EFalse; |
|
1849 err = AgpsInterface()->StartPositioning(iFsm->SessionId(), |
|
1850 iFsm->PosRequestMethod(), |
|
1851 iFsm->GpsRequestQuality(), |
|
1852 iFsm->IsEmergency()); |
|
1853 if (KErrNone == err) |
|
1854 { |
|
1855 iFsm->LocationUpdateTimer().EventAfter(iFsm->GpsRequestQuality().MaxFixTime(), 1); |
|
1856 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitReasonNone, KErrNone); |
|
1857 } |
|
1858 else |
|
1859 { |
|
1860 // Error sending the location request, send a location response |
|
1861 // with the error and go to Idle state. |
|
1862 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitBadLocationRequest, err); |
|
1863 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, iFsm->SessionId()); |
|
1864 } |
|
1865 } |
|
1866 |
|
1867 // ----------------------------------------------------------------------------- |
|
1868 // CLbsPrivLocWaitLocUpdateState::OnExit |
|
1869 // Description: Carries out tasks required on exit from the state. |
|
1870 // Cancels the location update request and stops the timer. |
|
1871 // ----------------------------------------------------------------------------- |
|
1872 // |
|
1873 TBool CLbsPrivLocWaitLocUpdateState::OnExit() |
|
1874 { |
|
1875 // Cancel the update timer. |
|
1876 iFsm->LocationUpdateTimer().Cancel(); |
|
1877 |
|
1878 TInt consumed = EFalse; |
|
1879 switch(iFsm->ExitData().iExitReason) |
|
1880 { |
|
1881 case TPrivLocStateExitData::EExitLocFixReceived: |
|
1882 { |
|
1883 // Don't cancel the location request yet, but tell the AGPS interface |
|
1884 // handler to put it on 'hold'. If we are in a hybrid or terminal-assisted |
|
1885 // request then we are going to get another location request very shortly |
|
1886 // anyway... |
|
1887 AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone); |
|
1888 |
|
1889 // Report the position to the message switch |
|
1890 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1891 iFsm->ExitData().iExitInfo, |
|
1892 iFsm->GpsRequestQuality(), |
|
1893 iFsm->GpsPosition(), |
|
1894 iFsm->ActualTime(), |
|
1895 iFsm->IsEmergency()); |
|
1896 |
|
1897 // For MTLR pass the data to the privacy handler |
|
1898 // in case the Privacy Controller wants it. |
|
1899 if ((iFsm->ExitData().iExitInfo >= KErrNone) && |
|
1900 (iFsm->ExitData().iExitInfo != KPositionCalculationFutile) && |
|
1901 ((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated) || |
|
1902 (iFsm->SessionType() == TLbsNetworkEnumInt::EServiceNetworkInduced))) |
|
1903 { |
|
1904 PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), |
|
1905 iFsm->GpsPosition()); |
|
1906 } |
|
1907 |
|
1908 consumed = ETrue; |
|
1909 break; |
|
1910 } |
|
1911 |
|
1912 case TPrivLocStateExitData::EExitLocMeasurementResultsReceived: |
|
1913 { |
|
1914 // Don't cancel the location request yet, but tell the AGPS interface |
|
1915 // handler to put it on 'hold'. If we are in a hybrid or terminal-assisted |
|
1916 // request then we are going to get another location request very shortly |
|
1917 // anyway... |
|
1918 AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone); |
|
1919 |
|
1920 // Report the measurement data to the message switch, even if we |
|
1921 // didn't get any. The error code will indicate that the data |
|
1922 // is rubbish in that case. |
|
1923 LBSLOG2(ELogP3, "CLbsPrivLocWaitLocUpdateState:returning with reason %d", iFsm->MeasurementInfoError()); |
|
1924 |
|
1925 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1926 iFsm->ExitData().iExitInfo, |
|
1927 iFsm->GpsRequestQuality(), |
|
1928 iFsm->GpsMeasurementInfo(), |
|
1929 iFsm->ActualTime(), |
|
1930 iFsm->IsEmergency()); |
|
1931 break; |
|
1932 } |
|
1933 |
|
1934 case TPrivLocStateExitData::EExitTimedOut: |
|
1935 { |
|
1936 // Don't cancel the location request yet, but tell the AGPS interface |
|
1937 // handler to put it on 'hold'. If we are in a hybrid or terminal-assisted |
|
1938 // request then we are going to get another location request very shortly |
|
1939 // anyway... |
|
1940 AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone); |
|
1941 |
|
1942 // If the request has timed out, then return whatever position |
|
1943 // data we have, but make it clear it's not what was requested. |
|
1944 // If there's an error (probably KErrTimedOut) there's |
|
1945 // nothing to report, so send dummy data with the error. |
|
1946 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1947 iFsm->ExitData().iExitInfo, |
|
1948 iFsm->GpsRequestQuality(), |
|
1949 iFsm->GpsPosition(), |
|
1950 iFsm->ActualTime(), |
|
1951 iFsm->IsEmergency()); |
|
1952 |
|
1953 // For MTLR, pass the data to the privacy handler in case the Privacy |
|
1954 // Controller wants it. |
|
1955 // NB Don't send the update if the error is KErrTimedOut, as that means there's |
|
1956 // nothing to report. |
|
1957 if((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated) && |
|
1958 (iFsm->ExitData().iExitInfo == KPositionQualityLoss)) |
|
1959 { |
|
1960 PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), |
|
1961 iFsm->GpsPosition()); |
|
1962 } |
|
1963 |
|
1964 consumed = ETrue; |
|
1965 break; |
|
1966 } |
|
1967 |
|
1968 case TPrivLocStateExitData::EExitCancelledByPrivacyController: |
|
1969 { |
|
1970 // Stop the location request immediately. |
|
1971 AgpsInterface()->StopPositioning(iFsm->SessionId()); |
|
1972 |
|
1973 // Send a SendExternalLocateCancel to NetGateWay- if the protcol module does not support this then |
|
1974 // the Gateway will do nothing |
|
1975 MessageSwitch()->SendExternalLocateCancel(iFsm->SessionId(), KErrCancel); |
|
1976 |
|
1977 // Send a location response with 'cancel' set to the network |
|
1978 TPositionInfo dummyPosInfo; |
|
1979 TTime dummyTime; |
|
1980 TLbsNetPosRequestQualityInt dummyQuality; |
|
1981 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
1982 iFsm->ExitData().iExitInfo, |
|
1983 dummyQuality, |
|
1984 dummyPosInfo, |
|
1985 dummyTime, |
|
1986 iFsm->IsEmergency()); |
|
1987 |
|
1988 consumed = ETrue; |
|
1989 } |
|
1990 break; |
|
1991 |
|
1992 case TPrivLocStateExitData::EExitBadQualityProfile: |
|
1993 { |
|
1994 // Do nothing; we're just going back to Idle state |
|
1995 consumed = ETrue; |
|
1996 break; |
|
1997 } |
|
1998 |
|
1999 case TPrivLocStateExitData::EExitBadLocationRequest: |
|
2000 { |
|
2001 // Error processing the location request - |
|
2002 // send a dummy response with an error code. |
|
2003 TPositionInfo dummyPosInfo; |
|
2004 TTime dummyTime; |
|
2005 TLbsNetPosRequestQualityInt dummyQuality; |
|
2006 MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), |
|
2007 iFsm->ExitData().iExitInfo, |
|
2008 dummyQuality, |
|
2009 dummyPosInfo, |
|
2010 dummyTime, |
|
2011 iFsm->IsEmergency()); |
|
2012 |
|
2013 consumed = ETrue; |
|
2014 break; |
|
2015 } |
|
2016 |
|
2017 default: |
|
2018 { |
|
2019 consumed = CLbsPrivLocStateBase::OnExit(); |
|
2020 // If the exit reason wasn't handled, panic (should only happen in development) |
|
2021 __ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitLocUpdateUnknownExitReason)); |
|
2022 } |
|
2023 } |
|
2024 return(consumed); |
|
2025 } |
|
2026 |
|
2027 // ----------------------------------------------------------------------------- |
|
2028 // CLbsPrivLocIdleState::OnNetLocRequest |
|
2029 // Description: The Message Switch has forwarded a request for a network |
|
2030 // location. |
|
2031 // ----------------------------------------------------------------------------- |
|
2032 // |
|
2033 void CLbsPrivLocWaitLocUpdateState::OnNetLocRequest(const TLbsNetSessionIdInt& aSessionId, |
|
2034 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
2035 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2036 TBool aIsEmergency, |
|
2037 const TLbsNetPosRequestQualityInt& aQuality) |
|
2038 { |
|
2039 TInt numMethods = aPosRequestMethod.NumPosMethods(); |
|
2040 if (numMethods==1) |
|
2041 { |
|
2042 TLbsNetPosMethodInt netPosMethod; |
|
2043 aPosRequestMethod.GetPosMethod(0,netPosMethod); |
|
2044 |
|
2045 if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)) |
|
2046 { |
|
2047 iFsm->TapMode() = ETrue; |
|
2048 } |
|
2049 } |
|
2050 if(aSessionId != iFsm->SessionId()) |
|
2051 { |
|
2052 /* This request is for a different session. Cancel the current one |
|
2053 * and start a new one. |
|
2054 */ |
|
2055 HandleLocRequest(aSessionId,aPosRequestMethod, |
|
2056 aSessionType,aIsEmergency, |
|
2057 aQuality); |
|
2058 } |
|
2059 else |
|
2060 { |
|
2061 LBSLOG(ELogP3, "CLbsPrivLocWaitLocUpdateState::OnNetLocRequest: Matching SessionId."); |
|
2062 TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId, |
|
2063 aPosRequestMethod, |
|
2064 aSessionType, |
|
2065 aIsEmergency, |
|
2066 aQuality); |
|
2067 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone); |
|
2068 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams); |
|
2069 } |
|
2070 } |
|
2071 |
|
2072 |
|
2073 void CLbsPrivLocWaitLocUpdateState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/, |
|
2074 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, |
|
2075 TBool /*aIsEmergency*/, |
|
2076 const TLbsExternalRequestInfo& /*aExternalRequestInfo*/, |
|
2077 const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/) |
|
2078 { |
|
2079 // this can never happen. If the Fsm is in the WaitLocUpdateState then |
|
2080 // any arrival of a MTLR request would start a new session and not |
|
2081 // implicitly cancel the ongoing MTLR and the OnMTLRRequest() |
|
2082 // would be directed to that session not this one |
|
2083 |
|
2084 } |
|
2085 |
|
2086 // ----------------------------------------------------------------------------- |
|
2087 // CLbsPrivLocWaitLocUpdateState::OnTimerEventL |
|
2088 // Description: The Location Update timer has expired. |
|
2089 // Cancel the request, and pass on the response if any has been received, |
|
2090 // otherwise report failure. |
|
2091 // ----------------------------------------------------------------------------- |
|
2092 // |
|
2093 void CLbsPrivLocWaitLocUpdateState::OnTimerEventL(TInt /*aTimerId*/) |
|
2094 { |
|
2095 LBSLOG(ELogP3, "CLbsPrivLocWaitLocUpdateState::OnTimerEventL"); |
|
2096 |
|
2097 if(iFsm->MeasurementInfoReceived()) |
|
2098 { |
|
2099 // A position fix may have been received, but it can't be accurate enough |
|
2100 // (otherwise the request would have been completed before timeout), so |
|
2101 // return the most recent measurement info |
|
2102 LBSLOG(ELogP3, "OnTimerEventL, measurement data received"); |
|
2103 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, |
|
2104 iFsm->MeasurementInfoError()); |
|
2105 } |
|
2106 else if(iFsm->LocationFixReceived()) |
|
2107 { |
|
2108 // position received, but not accurate enough (or request would already have been completed) |
|
2109 LBSLOG(ELogP3, "OnTimerEventL, inaccurate location data received"); |
|
2110 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitTimedOut, |
|
2111 KPositionQualityLoss); |
|
2112 } |
|
2113 else |
|
2114 { |
|
2115 // we've received no update (position / measurements) |
|
2116 LBSLOG(ELogP3, "OnTimerEventL, NO measurement data received"); |
|
2117 LBSLOG(ELogP3, "(Setting exit info KErrPositionNoGpsUpdate"); |
|
2118 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitTimedOut, |
|
2119 KErrPositionNoGpsUpdate); |
|
2120 } |
|
2121 |
|
2122 SetExitState(); |
|
2123 } |
|
2124 |
|
2125 // ----------------------------------------------------------------------------- |
|
2126 // CLbsPrivLocWaitLocUpdateState::SetExitState |
|
2127 // Description: Works out the next state on the basis of the current session |
|
2128 // type and whether any update has been received. |
|
2129 // ----------------------------------------------------------------------------- |
|
2130 // |
|
2131 void CLbsPrivLocWaitLocUpdateState::SetExitState() |
|
2132 { |
|
2133 TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(), |
|
2134 iFsm->IsEmergency(), |
|
2135 EFalse, |
|
2136 iFsm->ExitData().iExitInfo); |
|
2137 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, |
|
2138 locationRequestParams); |
|
2139 } |
|
2140 |
|
2141 TBool CLbsPrivLocWaitLocUpdateState::ReceivedFixIsAccurate() |
|
2142 { |
|
2143 TBool fixIsAccurate = EFalse; |
|
2144 |
|
2145 // Compare the accuracy to the request values. |
|
2146 // Make sure the location update is (A)GPS and not Network based. |
|
2147 TPosition latestPosition; |
|
2148 iFsm->GpsPosition().GetPosition(latestPosition); |
|
2149 |
|
2150 if ((latestPosition.HorizontalAccuracy() <= iFsm->GpsRequestQuality().MinHorizontalAccuracy()) && |
|
2151 (latestPosition.VerticalAccuracy() <= iFsm->GpsRequestQuality().MinVerticalAccuracy()) && |
|
2152 (iFsm->GpsPosition().PositionMode() != TPositionModuleInfo::ETechnologyNetwork))//Pure Reference Location |
|
2153 { |
|
2154 fixIsAccurate = ETrue; |
|
2155 } |
|
2156 |
|
2157 return(fixIsAccurate); |
|
2158 } |
|
2159 |
|
2160 /** Callback when a GPS position update arrives from AGPS manager. |
|
2161 */ |
|
2162 void CLbsPrivLocWaitLocUpdateState::OnAgpsPositionUpdate( |
|
2163 TInt aReason, |
|
2164 const TPositionExtendedSatelliteInfo& aPosInfo, |
|
2165 const TTime& aTimeStamp) |
|
2166 { |
|
2167 iFsm->GpsPosition() = aPosInfo; |
|
2168 iFsm->ActualTime() = aTimeStamp; |
|
2169 iFsm->LocationFixReceived() = ETrue; |
|
2170 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, aReason); |
|
2171 |
|
2172 if (KErrNone == aReason) |
|
2173 { |
|
2174 if (iFsm->TapMode()) |
|
2175 { |
|
2176 LBSLOG(ELogP1,"TAP mode) - NOT sending position to network"); |
|
2177 return; // do NOT return AGPS postions to TAP mode sessions |
|
2178 } |
|
2179 // See if the reported accuracy matches the specified quality. |
|
2180 // If the accuracy is good enough, report the position |
|
2181 |
|
2182 // if this session is TAP then discard the position |
|
2183 |
|
2184 if(ReceivedFixIsAccurate()) |
|
2185 { |
|
2186 SetExitState(); |
|
2187 } |
|
2188 } |
|
2189 else if ((aReason <= KErrNone) || (KPositionCalculationFutile == aReason)) |
|
2190 { |
|
2191 // GPS Manager can't provide a location update. return what we do have. |
|
2192 if(iFsm->MeasurementInfoReceived()) |
|
2193 { |
|
2194 LBSLOG(ELogP1,"CLbsPrivLocWaitLocUpdateState::OnPositionUpdate() - measurement received"); |
|
2195 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, aReason); |
|
2196 } |
|
2197 else |
|
2198 { |
|
2199 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, aReason); |
|
2200 } |
|
2201 SetExitState(); |
|
2202 } |
|
2203 else if (KPositionEarlyComplete == aReason) |
|
2204 { |
|
2205 // Not an error. Report back what was accepted. |
|
2206 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, KErrNone); |
|
2207 SetExitState(); |
|
2208 } |
|
2209 else |
|
2210 { |
|
2211 // A real error |
|
2212 SetExitState(); |
|
2213 } |
|
2214 } |
|
2215 |
|
2216 /** Callback when a GPS measurement results update arrives from AGPS manager. |
|
2217 |
|
2218 Only location requests that are 'hybrid' or 'terminal assisted' should record |
|
2219 the measurement results. Other types of request (autonomous, terminal based) |
|
2220 are only interested in the GPS position update. |
|
2221 */ |
|
2222 void CLbsPrivLocWaitLocUpdateState::OnAgpsMeasurementUpdate( |
|
2223 TInt aReason, |
|
2224 const TPositionGpsMeasurementInfo& aPosInfo, |
|
2225 const TTime& /*aTimeStamp*/) |
|
2226 { |
|
2227 // Check that we should be listening for measurement updates. |
|
2228 |
|
2229 TBool positionCalculationPossible = aPosInfo.PositionCalculationPossible(); |
|
2230 |
|
2231 const TInt methodCount = iFsm->PosRequestMethod().NumPosMethods(); |
|
2232 for(TInt i = 0; i < methodCount; ++i) |
|
2233 { |
|
2234 TLbsNetPosMethodInt posMethod; |
|
2235 iFsm->PosRequestMethod().GetPosMethod(i, posMethod); |
|
2236 if((posMethod.PosMode() & KTerminalAssistedMode) == KTerminalAssistedMode) |
|
2237 { |
|
2238 iFsm->MeasurementInfoReceived() = ETrue; |
|
2239 iFsm->MeasurementInfoError() = aReason; |
|
2240 iFsm->GpsMeasurementInfo() = aPosInfo; |
|
2241 |
|
2242 // don't wait until alpha2 time expires, instead |
|
2243 // return measuremnts now |
|
2244 if (positionCalculationPossible) |
|
2245 { |
|
2246 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, |
|
2247 iFsm->MeasurementInfoError()); |
|
2248 SetExitState(); |
|
2249 } |
|
2250 break; |
|
2251 } |
|
2252 } |
|
2253 } |
|
2254 |
|
2255 /** Callback when a GPS measurement results update arrives from AGPS manager. |
|
2256 |
|
2257 Only location requests that are 'hybrid' or 'terminal assisted' should record |
|
2258 the measurement results. Other types of request (autonomous, terminal based) |
|
2259 are only interested in the GPS position update. |
|
2260 */ |
|
2261 void CLbsPrivLocWaitLocUpdateState::OnNetLocReferenceUpdate( |
|
2262 const TLbsNetSessionIdInt& aSessionId, |
|
2263 const TPositionInfoBase& aPosInfo) |
|
2264 { |
|
2265 CLbsPrivLocStateBase::OnNetLocReferenceUpdate(aSessionId,aPosInfo); |
|
2266 } |
|
2267 |
|
2268 |
|
2269 // ----------------------------------------------------------------------------- |
|
2270 // |
|
2271 // ----------------------- Class CLbsPrivLocWaitLocReqState -------------------- |
|
2272 // |
|
2273 // Implements the Wait For Location Request state of the Privacy and Location |
|
2274 // Request Handler |
|
2275 // |
|
2276 // ----------------------------------------------------------------------------- |
|
2277 // |
|
2278 CLbsPrivLocWaitLocReqState* CLbsPrivLocWaitLocReqState::NewL(CLbsPrivLocFsm* aFsm) |
|
2279 { |
|
2280 return new(ELeave)CLbsPrivLocWaitLocReqState(aFsm); |
|
2281 } |
|
2282 |
|
2283 CLbsPrivLocWaitLocReqState::CLbsPrivLocWaitLocReqState(CLbsPrivLocFsm* aFsm) |
|
2284 : CLbsPrivLocStateBase(aFsm) |
|
2285 { |
|
2286 } |
|
2287 |
|
2288 // ----------------------------------------------------------------------------- |
|
2289 // CLbsPrivLocWaitLocReqState::OnEntry |
|
2290 // Description: Carries out tasks required on entry to the state. |
|
2291 // ----------------------------------------------------------------------------- |
|
2292 // |
|
2293 void CLbsPrivLocWaitLocReqState::OnEntry(const TPrivLocCommonParams& aStateParams) |
|
2294 { |
|
2295 CLbsPrivLocStateBase::OnEntry(aStateParams); |
|
2296 const TPrivLocWaitLocationRequestParams& params = TPrivLocWaitLocationRequestParams::Cast(aStateParams); |
|
2297 iFsm->IsEmergency() = params.iIsEmergency; |
|
2298 iFsm->PrivacyRequestCancelled() = params.iReqCancelled; |
|
2299 iFsm->PreviousStateExitInfo() = params.iPreviousStateExitInfo; |
|
2300 } |
|
2301 |
|
2302 |
|
2303 // ----------------------------------------------------------------------------- |
|
2304 // CLbsPrivLocWaitLocReqState::OnExit |
|
2305 // Description: Carries out tasks required on exit from the state. |
|
2306 // Panics if the exit reason is not handled by the base state exit |
|
2307 // ----------------------------------------------------------------------------- |
|
2308 // |
|
2309 TBool CLbsPrivLocWaitLocReqState::OnExit() |
|
2310 { |
|
2311 TBool consumed = CLbsPrivLocStateBase::OnExit(); |
|
2312 // If the exit reason wasn't handled, panic (should only happen in development) |
|
2313 __ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitLocReqUnknownExitReason)); |
|
2314 return(consumed); |
|
2315 } |
|
2316 |
|
2317 void CLbsPrivLocWaitLocReqState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/, |
|
2318 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, |
|
2319 TBool /*aIsEmergency*/, |
|
2320 const TLbsExternalRequestInfo& /*aExternalRequestInfo*/, |
|
2321 const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/) |
|
2322 { |
|
2323 // this can never happen. If the Fsm is in the WaitLocReqState then |
|
2324 // any arrival of a MTLR request would start a new session and the OnMTLRRequest() |
|
2325 // would be directed to that session not this one |
|
2326 __ASSERT_DEBUG(EFalse, Panic(ENrhPanicBadParamType)); |
|
2327 } |
|
2328 |
|
2329 void CLbsPrivLocWaitLocReqState::OnNetLocRequest(const TLbsNetSessionIdInt& aSessionId, |
|
2330 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
2331 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2332 TBool aIsEmergency, |
|
2333 const TLbsNetPosRequestQualityInt& aQuality) |
|
2334 { |
|
2335 TInt numMethods = aPosRequestMethod.NumPosMethods(); |
|
2336 if (numMethods==1) |
|
2337 { |
|
2338 TLbsNetPosMethodInt netPosMethod; |
|
2339 aPosRequestMethod.GetPosMethod(0,netPosMethod); |
|
2340 |
|
2341 if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted)) |
|
2342 { |
|
2343 iFsm->TapMode() = ETrue; |
|
2344 } |
|
2345 } |
|
2346 |
|
2347 |
|
2348 if(aSessionId == iFsm->SessionId()) |
|
2349 { |
|
2350 if (iFsm->PrivacyRequestCancelled()) |
|
2351 { |
|
2352 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrCancel); |
|
2353 TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(), |
|
2354 iFsm->IsEmergency(), |
|
2355 iFsm->PrivacyRequestCancelled()); |
|
2356 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams); |
|
2357 } |
|
2358 else |
|
2359 { |
|
2360 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone); |
|
2361 TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId, |
|
2362 aPosRequestMethod, |
|
2363 aSessionType, |
|
2364 aIsEmergency, |
|
2365 aQuality); |
|
2366 iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams); |
|
2367 } |
|
2368 } |
|
2369 else |
|
2370 { |
|
2371 HandleLocRequest(aSessionId,aPosRequestMethod, |
|
2372 aSessionType,aIsEmergency, |
|
2373 aQuality); |
|
2374 } |
|
2375 } |
|
2376 |
|
2377 void CLbsPrivLocWaitLocReqState::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aSessionId) |
|
2378 { |
|
2379 if (!iFsm->IsEmergency() && (aSessionId == iFsm->SessionId())) |
|
2380 { |
|
2381 if (!iFsm->PrivacyRequestCancelled() ) |
|
2382 { |
|
2383 TLbsNetSessionIdInt sessionId = iFsm->SessionId(); |
|
2384 MessageSwitch()->SendExternalLocateCancel(sessionId,KErrCancel); |
|
2385 } |
|
2386 iFsm->PrivacyRequestCancelled() = ETrue; |
|
2387 } |
|
2388 } |
|
2389 |
|
2390 |
|
2391 /** Called when a reference position arrives from the network. |
|
2392 */ |
|
2393 void CLbsPrivLocWaitLocReqState::OnNetLocReferenceUpdate( |
|
2394 const TLbsNetSessionIdInt& aSessionId, |
|
2395 const TPositionInfoBase& aPosInfo) |
|
2396 { |
|
2397 // if the MTLR is still active (has not been cancelled by the privacy handler) |
|
2398 if (!iFsm->PrivacyRequestCancelled()) |
|
2399 { |
|
2400 CLbsPrivLocStateBase::OnNetLocReferenceUpdate(aSessionId, aPosInfo); |
|
2401 } |
|
2402 } |
|
2403 |
|
2404 // ----------------------------------------------------------------------------- |
|
2405 // CLbsPrivLocWaitLocReqState::OnSessionComplete |
|
2406 // Description: handling of a session complete message |
|
2407 // ----------------------------------------------------------------------------- |
|
2408 // |
|
2409 void CLbsPrivLocWaitLocReqState::OnSessionComplete(const TLbsNetSessionIdInt& aSessionId, |
|
2410 TInt aReason) |
|
2411 { |
|
2412 |
|
2413 |
|
2414 if(aSessionId == iFsm->SessionId()) |
|
2415 { |
|
2416 // Make sure the reason passed with the Session Complete is sent to the |
|
2417 // Privacy Controller EXCEPT when the update previously passed to the |
|
2418 // network didn't meet the quality criteria. In this case use the |
|
2419 // KPositionQualityLoss status. |
|
2420 TInt completionReason = aReason; |
|
2421 if(aReason == KErrNone) |
|
2422 { |
|
2423 if(KPositionQualityLoss == iFsm->PreviousStateExitInfo()) |
|
2424 { |
|
2425 completionReason = KPositionQualityLoss; |
|
2426 } |
|
2427 } |
|
2428 |
|
2429 iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, completionReason); |
|
2430 iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId); |
|
2431 } |
|
2432 } |
|
2433 |
|
2434 // ----------------------------------------------------------------------------- |
|
2435 // |
|
2436 // Package classes |
|
2437 // |
|
2438 // ----------------------------------------------------------------------------- |
|
2439 // |
|
2440 TPrivLocCommonParams::TPrivLocCommonParams() |
|
2441 { |
|
2442 } |
|
2443 TPrivLocCommonParams::TPrivLocCommonParams(TLbsNetSessionIdInt aSessionId) |
|
2444 { |
|
2445 iSessionId = aSessionId; |
|
2446 } |
|
2447 |
|
2448 TPrivLocWaitLocationRequestParams::TPrivLocWaitLocationRequestParams() |
|
2449 { |
|
2450 } |
|
2451 TPrivLocWaitLocationRequestParams::TPrivLocWaitLocationRequestParams( |
|
2452 const TLbsNetSessionIdInt& aSessionId, |
|
2453 TBool aIsEmergency, |
|
2454 TBool aReqCancelled, |
|
2455 TInt aPreviousStateExitInfo) : |
|
2456 TPrivLocCommonParams(aSessionId), |
|
2457 iIsEmergency(aIsEmergency), |
|
2458 iReqCancelled(aReqCancelled), |
|
2459 iPreviousStateExitInfo(aPreviousStateExitInfo) |
|
2460 { |
|
2461 } |
|
2462 |
|
2463 TPrivLocWaitLocationUpdateParams::TPrivLocWaitLocationUpdateParams() |
|
2464 { |
|
2465 } |
|
2466 TPrivLocWaitLocationUpdateParams::TPrivLocWaitLocationUpdateParams( |
|
2467 const TLbsNetSessionIdInt& aSessionId, |
|
2468 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
2469 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2470 TBool aIsEmergency, |
|
2471 const TLbsNetPosRequestQualityInt& aQuality) : |
|
2472 TPrivLocCommonParams(aSessionId), |
|
2473 iSessionType(aSessionType), |
|
2474 iIsEmergency(aIsEmergency), |
|
2475 iQuality(aQuality), |
|
2476 iPosRequestMethod(aPosRequestMethod) |
|
2477 { |
|
2478 } |
|
2479 |
|
2480 TPrivLocWaitPrivResponseParams::TPrivLocWaitPrivResponseParams() |
|
2481 { |
|
2482 |
|
2483 } |
|
2484 TPrivLocWaitPrivResponseParams::TPrivLocWaitPrivResponseParams( |
|
2485 const TLbsNetSessionIdInt& aSessionId, |
|
2486 const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2487 const TLbsExternalRequestInfo& aExternalRequestInfo, |
|
2488 const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy, |
|
2489 TBool aIsEmergency) : |
|
2490 TPrivLocCommonParams(aSessionId), |
|
2491 iNetPosRequestPrivacy(aNetPosRequestPrivacy), |
|
2492 iIsEmergency(aIsEmergency), |
|
2493 iSessionType(aSessionType) |
|
2494 { |
|
2495 // Need to check the type of aExternalRequestInfo before |
|
2496 // copying it into this class. |
|
2497 if (aExternalRequestInfo.ClassType() == EExternalRequestInfoClass) |
|
2498 { |
|
2499 __ASSERT_DEBUG(aExternalRequestInfo.ClassSize() == sizeof(TLbsExternalRequestInfo), |
|
2500 Panic(ENrhPanicInvalidExternalRequestInfoType)); |
|
2501 |
|
2502 Mem::Copy(&iExternalRequestInfo, |
|
2503 &aExternalRequestInfo, |
|
2504 sizeof(TLbsExternalRequestInfo)); |
|
2505 } |
|
2506 else |
|
2507 { |
|
2508 if (aExternalRequestInfo.ClassType() == (EExternalRequestInfoClass | EExternalRequestInfoClass2)) |
|
2509 { |
|
2510 __ASSERT_DEBUG(aExternalRequestInfo.ClassSize() == sizeof(TLbsExternalRequestInfo2), |
|
2511 Panic(ENrhPanicInvalidExternalRequestInfoType)); |
|
2512 |
|
2513 Mem::Copy(&iExternalRequestInfo, |
|
2514 &aExternalRequestInfo, |
|
2515 sizeof(TLbsExternalRequestInfo2)); |
|
2516 } |
|
2517 else |
|
2518 { |
|
2519 Panic(ENrhPanicInvalidExternalRequestInfoType); |
|
2520 } |
|
2521 } |
|
2522 } |
|
2523 |
|
2524 // ----------------------------------------------------------------------------- |
|
2525 // |
|
2526 // ----------------------------- Class CLbsPrivLocFsm -------------------------- |
|
2527 // |
|
2528 // State Machine class which owns the states of the Privacy and Location Handler |
|
2529 // |
|
2530 // ----------------------------------------------------------------------------- |
|
2531 // |
|
2532 |
|
2533 // ----------------------------------------------------------------------------- |
|
2534 // CLbsPrivLocFsm::NewL |
|
2535 // Description: CLbsPrivLocFsm static constructor |
|
2536 // ----------------------------------------------------------------------------- |
|
2537 // |
|
2538 CLbsPrivLocFsm* CLbsPrivLocFsm::NewL( |
|
2539 CPrivacyAndLocationHandler& aPrivLocHandler, |
|
2540 const TLbsNetSessionIdInt& aSessionId) |
|
2541 { |
|
2542 CLbsPrivLocFsm* self; |
|
2543 self = new (ELeave) CLbsPrivLocFsm(aPrivLocHandler, aSessionId); |
|
2544 CleanupStack::PushL(self); |
|
2545 self->ConstructL(); |
|
2546 CleanupStack::Pop(self); |
|
2547 return(self); |
|
2548 } |
|
2549 |
|
2550 // ----------------------------------------------------------------------------- |
|
2551 // CLbsPrivLocFsm::CLbsPrivLocFsm |
|
2552 // Description: CLbsPrivLocFsm constructor |
|
2553 // ----------------------------------------------------------------------------- |
|
2554 // |
|
2555 CLbsPrivLocFsm::CLbsPrivLocFsm( |
|
2556 CPrivacyAndLocationHandler& aPrivLocHandler, |
|
2557 const TLbsNetSessionIdInt& aSessionId) : |
|
2558 iPrivLocHandler(aPrivLocHandler), |
|
2559 iSessionId(aSessionId), |
|
2560 iIsEmergency(EFalse), |
|
2561 iSessionType(TLbsNetworkEnumInt::EServiceNone), |
|
2562 iRefPosProcessed(EFalse), |
|
2563 iLocReqReceived(EFalse), |
|
2564 iReqCancelled(EFalse), |
|
2565 iWasPrivacyResponseReceivedStateExited(EFalse), |
|
2566 iPositioningStatusIncremented(EFalse) |
|
2567 { |
|
2568 } |
|
2569 |
|
2570 // ----------------------------------------------------------------------------- |
|
2571 // CLbsPrivLocFsm::~CLbsPrivLocFsm |
|
2572 // Description: CLbsPrivLocFsm destructor |
|
2573 // ----------------------------------------------------------------------------- |
|
2574 // |
|
2575 CLbsPrivLocFsm::~CLbsPrivLocFsm() |
|
2576 { |
|
2577 delete iLocationUpdateTimer; |
|
2578 iStates.DeleteAll(); |
|
2579 iStates.Reset(); |
|
2580 } |
|
2581 |
|
2582 // ----------------------------------------------------------------------------- |
|
2583 // CLbsPrivLocFsm::SessionId |
|
2584 // Description: Get the current session Id for this FSM. |
|
2585 // ----------------------------------------------------------------------------- |
|
2586 // |
|
2587 const TLbsNetSessionIdInt& CLbsPrivLocFsm::SessionId() const |
|
2588 { |
|
2589 return iSessionId; |
|
2590 } |
|
2591 |
|
2592 // ----------------------------------------------------------------------------- |
|
2593 // CLbsPrivLocFsm::ConstructL |
|
2594 // Description: CLbsPrivLocFsm second-phase constructor. |
|
2595 // Creates the states of the system and the Privacy Handler. |
|
2596 // ----------------------------------------------------------------------------- |
|
2597 // |
|
2598 void CLbsPrivLocFsm::ConstructL() |
|
2599 { |
|
2600 // Create the states |
|
2601 iStates.At(EStateIdle) = CLbsPrivLocIdleState::NewL(this); |
|
2602 iStates.At(EStateWaitPrivacyResponse) = CLbsPrivLocWaitPrivRespState::NewL(this); |
|
2603 iStates.At(EStateWaitLocationRequest) = CLbsPrivLocWaitLocReqState::NewL(this); |
|
2604 iStates.At(EStateWaitLocationUpdate) = CLbsPrivLocWaitLocUpdateState::NewL(this); |
|
2605 |
|
2606 iCurrentState = iStates.At(EStateIdle); |
|
2607 // When waiting for an update, there is a maximum duration specified by the |
|
2608 // LBS admin data to avoid the risk of hanging around forever in the event of |
|
2609 // a problem with the A-GPS module. Create a timer to deal with this. |
|
2610 iLocationUpdateTimer = CLbsCallbackTimer::NewL(*this); |
|
2611 } |
|
2612 |
|
2613 |
|
2614 TBool CLbsPrivLocFsm::IsSpecialFeatureIntermediateFutileUpdateOn() |
|
2615 { |
|
2616 return PrivLocHandler().IsSpecialFeatureIntermediateFutileUpdateOn(); |
|
2617 } |
|
2618 |
|
2619 // ----------------------------------------------------------------------------- |
|
2620 // CPrivacyAndLocationHandler::SetServerObserver |
|
2621 // Description: Store a pointer to the NRH server which comunicates with the |
|
2622 // Privacy Controller. |
|
2623 // ----------------------------------------------------------------------------- |
|
2624 // |
|
2625 void CLbsPrivLocFsm::SetServerObserver(MLbsSessionObserver* aNrhServer) |
|
2626 { |
|
2627 PrivLocHandler().PrivacyHandler()->SetServerObserver(aNrhServer); |
|
2628 } |
|
2629 |
|
2630 // ----------------------------------------------------------------------------- |
|
2631 // CLbsPrivLocFsm::OnRespondNetworkLocationRequest |
|
2632 // Description: Called by the Privacy Handler to report the result of a privacy |
|
2633 // check. Handling of the response is delegated to the current state. |
|
2634 // ----------------------------------------------------------------------------- |
|
2635 // |
|
2636 void CLbsPrivLocFsm::OnRespondNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId, |
|
2637 TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult, |
|
2638 TInt aResponseReason) |
|
2639 { |
|
2640 LBSLOG3(ELogP3, "FSM(%d) OnRespondNetworkLocationRequest response=%d",iSessionId.SessionNum(),aRequestResult); |
|
2641 iCurrentState->OnRespondNetworkLocationRequest(aRequestId, aRequestResult, aResponseReason); |
|
2642 } |
|
2643 |
|
2644 // ----------------------------------------------------------------------------- |
|
2645 // CLbsPrivLocFsm::OnCancelNetworkLocationRequest |
|
2646 // Description: Called by the Privacy Handler to report that a privacy check |
|
2647 // has been rejected. This may occur after it has already been accepted. |
|
2648 // Handling of the response is delegated to the current state. |
|
2649 // ----------------------------------------------------------------------------- |
|
2650 // |
|
2651 void CLbsPrivLocFsm::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId) |
|
2652 { |
|
2653 LBSLOG2(ELogP3, "FSM(%d) OnCancelNetworkLocationRequest",iSessionId.SessionNum()); |
|
2654 iCurrentState->OnCancelNetworkLocationRequest(aRequestId); |
|
2655 } |
|
2656 |
|
2657 // ----------------------------------------------------------------------------- |
|
2658 // CLbsPrivLocFsm::OnMTLRRequest |
|
2659 // Description: The Message Switch has forwarded a request to start an MTLR |
|
2660 // session. |
|
2661 // Handling of the request is delegated to the current state. |
|
2662 // ----------------------------------------------------------------------------- |
|
2663 // |
|
2664 void CLbsPrivLocFsm::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId, |
|
2665 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2666 TBool aIsEmergency, |
|
2667 const TLbsExternalRequestInfo& aExternalRequestInfo, |
|
2668 const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy) |
|
2669 { |
|
2670 LBSLOG2(ELogP3, "FSM(%d) OnMTLRRequest",iSessionId.SessionNum()); |
|
2671 iCurrentState->OnMTLRRequest(aSessionId, |
|
2672 aSessionType, |
|
2673 aIsEmergency, |
|
2674 aExternalRequestInfo, |
|
2675 aNetPosRequestPrivacy); |
|
2676 } |
|
2677 |
|
2678 // ----------------------------------------------------------------------------- |
|
2679 // CLbsPrivLocFsm::OnSessionComplete |
|
2680 // Description: The Message Switch has reported that the session is |
|
2681 // over (complete or aborted due to some error). |
|
2682 // Handling of the message is delegated to the current state. |
|
2683 // ----------------------------------------------------------------------------- |
|
2684 // |
|
2685 void CLbsPrivLocFsm::OnSessionComplete( |
|
2686 const TLbsNetSessionIdInt& aSessionId, |
|
2687 TInt aReason) |
|
2688 { |
|
2689 LBSLOG3(ELogP3, "FSM(%d) OnSessionComplete reason=%d",iSessionId.SessionNum(),aReason); |
|
2690 iCurrentState->OnSessionComplete(aSessionId, aReason); |
|
2691 |
|
2692 // update the positioning status. Note this is updated only if it was previously |
|
2693 // incremented as a result of this session. |
|
2694 if (WasPositioningStatusIncremented()) |
|
2695 { |
|
2696 PrivLocHandler().DecrementPositioningStatus(); |
|
2697 WasPositioningStatusIncremented() = EFalse; |
|
2698 } |
|
2699 } |
|
2700 |
|
2701 // ----------------------------------------------------------------------------- |
|
2702 // CLbsPrivLocFsm::OnNetLocRequest |
|
2703 // Description: The Message Switch has passed on a request for a position update |
|
2704 // Handling of the request is delegated to the current state. |
|
2705 // ----------------------------------------------------------------------------- |
|
2706 // |
|
2707 void CLbsPrivLocFsm::OnNetLocRequest( |
|
2708 const TLbsNetSessionIdInt& aSessionId, |
|
2709 const TLbsNetPosRequestMethodInt& aPosRequestMethod, |
|
2710 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, |
|
2711 TBool aIsEmergency, |
|
2712 const TLbsNetPosRequestQualityInt& aQuality) |
|
2713 { |
|
2714 LBSLOG2(ELogP3, "FSM(%d) OnNetLocRequest",iSessionId.SessionNum()); |
|
2715 iCurrentState->OnNetLocRequest(aSessionId, |
|
2716 aPosRequestMethod, |
|
2717 aSessionType, |
|
2718 aIsEmergency, |
|
2719 aQuality); |
|
2720 } |
|
2721 |
|
2722 /** Called when a reference position arrives from the network. |
|
2723 */ |
|
2724 void CLbsPrivLocFsm::OnNetLocReferenceUpdate( |
|
2725 const TLbsNetSessionIdInt& aSessionId, |
|
2726 const TPositionInfoBase& aPosInfo) |
|
2727 { |
|
2728 LBSLOG2(ELogP3, "FSM(%d) OnNetLocReferenceUpdate",iSessionId.SessionNum()); |
|
2729 iCurrentState->OnNetLocReferenceUpdate(aSessionId, aPosInfo); |
|
2730 } |
|
2731 |
|
2732 /** Callend when a final location arrives from the network. |
|
2733 |
|
2734 Currently the final network position is never used by the |
|
2735 state machine - it is only needed by the X3P handler. |
|
2736 So this function just ignores the update. |
|
2737 */ |
|
2738 void CLbsPrivLocFsm::OnNetLocFinalUpdate( |
|
2739 const TLbsNetSessionIdInt& /*aSessionId*/, |
|
2740 const TPositionInfoBase& /*aPosInfo*/) |
|
2741 { |
|
2742 // Final network position not used by CLbsPrivLocFsm, so ignore it. |
|
2743 } |
|
2744 |
|
2745 // ----------------------------------------------------------------------------- |
|
2746 // CLbsPrivLocFsm::ChangeState |
|
2747 // Description: Called by a state of the FSM when a transition is required. |
|
2748 // ----------------------------------------------------------------------------- |
|
2749 // |
|
2750 void CLbsPrivLocFsm::ChangeState(TLocPrivacyHandlerState aNewStateId,const TPrivLocCommonParams& aStateParams) |
|
2751 { |
|
2752 // Tidy up the old state |
|
2753 if(iCurrentState) |
|
2754 { |
|
2755 // coverity[unchecked_value] |
|
2756 // We're not interested in whether it was consumed here |
|
2757 iCurrentState->OnExit(); |
|
2758 } |
|
2759 |
|
2760 // Note, here the session ID has already being set when the Fsm was created (when session first came into being) |
|
2761 // so no need to do this ... iSessionId = aStateParams.iSessionId; |
|
2762 |
|
2763 // Set the new state |
|
2764 iCurrentState = iStates.At(aNewStateId); |
|
2765 |
|
2766 LBSLOG3(ELogP3, "FSM(%d) Entering state %d",iSessionId.SessionNum(), aNewStateId); |
|
2767 |
|
2768 // Do any initialisation for the new state. |
|
2769 iCurrentState->OnEntry(aStateParams); |
|
2770 } |
|
2771 |
|
2772 // ----------------------------------------------------------------------------- |
|
2773 // CLbsPrivLocFsm::ChangeState |
|
2774 // Description: Called by a state of the FSM when a transition is required to a |
|
2775 // state which only requires the session Id |
|
2776 // ----------------------------------------------------------------------------- |
|
2777 // |
|
2778 void CLbsPrivLocFsm::ChangeState(TLocPrivacyHandlerState aNewStateId, |
|
2779 const TLbsNetSessionIdInt& aSessionId) |
|
2780 { |
|
2781 TPrivLocCommonParams commonParams(aSessionId); |
|
2782 ChangeState(aNewStateId, commonParams); |
|
2783 } |
|
2784 |
|
2785 // ----------------------------------------------------------------------------- |
|
2786 // CLbsPrivLocFsm::PrivLocHandler |
|
2787 // Description: Get the CPrivacyAndLocationHandler object |
|
2788 // ----------------------------------------------------------------------------- |
|
2789 // |
|
2790 CPrivacyAndLocationHandler& CLbsPrivLocFsm::PrivLocHandler() |
|
2791 { |
|
2792 return iPrivLocHandler; |
|
2793 } |
|
2794 |
|
2795 // ----------------------------------------------------------------------------- |
|
2796 // CLbsPrivLocWaitLocUpdateState::OnTimerEventL |
|
2797 // Description: The Location Update timer has expired. |
|
2798 // Cancel the request, and pass on the response if any has been received, |
|
2799 // otherwise report failure. |
|
2800 // ----------------------------------------------------------------------------- |
|
2801 // |
|
2802 void CLbsPrivLocFsm::OnTimerEventL(TInt aTimerId) |
|
2803 { |
|
2804 LBSLOG2(ELogP3, "FSM(%d) OnTimerEventL", iSessionId.SessionNum()); |
|
2805 iCurrentState->OnTimerEventL(aTimerId); |
|
2806 } |
|
2807 |
|
2808 /** Called if OnTimerEventL leaves */ |
|
2809 TInt CLbsPrivLocFsm::OnTimerError(TInt /*aTimerId*/, TInt aError) |
|
2810 { |
|
2811 __ASSERT_DEBUG(EFalse, Panic(ENrhPanicLocationTimerError)); |
|
2812 return(aError); |
|
2813 } |
|
2814 |
|
2815 /** Callback when a GPS position update arrives from AGPS manager. |
|
2816 */ |
|
2817 void CLbsPrivLocFsm::OnAgpsPositionUpdate( |
|
2818 TInt aReason, |
|
2819 const TPositionExtendedSatelliteInfo& aPosInfo, |
|
2820 const TTime& aTimeStamp) |
|
2821 { |
|
2822 LBSLOG2(ELogP3, "FSM(%d) OnAgpsPositionUpdate", iSessionId.SessionNum()); |
|
2823 iCurrentState->OnAgpsPositionUpdate(aReason, aPosInfo, aTimeStamp); |
|
2824 } |
|
2825 |
|
2826 /** Callback when a GPS measurement results update arrives from AGPS manager. |
|
2827 */ |
|
2828 void CLbsPrivLocFsm::OnAgpsMeasurementUpdate( |
|
2829 TInt aReason, |
|
2830 const TPositionGpsMeasurementInfo& aPosInfo, |
|
2831 const TTime& aTimeStamp) |
|
2832 { |
|
2833 LBSLOG2(ELogP3, "FSM(%d) OnAgpsMeasurementUpdate", iSessionId.SessionNum()); |
|
2834 iCurrentState->OnAgpsMeasurementUpdate(aReason, aPosInfo, aTimeStamp); |
|
2835 } |