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