|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // This file provides the implementation of the class for |
|
15 // the SUPL MO-LR procedure state handler |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file |
|
21 @internalTechnology |
|
22 @deprecated |
|
23 */ |
|
24 |
|
25 #include "suplmolrfsmsession.h" |
|
26 #include "suplmolrstatehandler.h" |
|
27 #include "suplgatewayinterface.h" |
|
28 #include "suplmessagebase.h" |
|
29 #include "suplstart.h" |
|
30 #include "suplpos.h" |
|
31 #include "suplposinit.h" |
|
32 #include "suplresponse.h" |
|
33 #include "suplend.h" |
|
34 #include <etelmm.h> |
|
35 #include "supldevloggermacros.h" |
|
36 |
|
37 |
|
38 /** Static constructor. |
|
39 @param aMachine A reference to the parent state machine. |
|
40 @return A new instance of the CSuplMoLrStateHandler class |
|
41 */ |
|
42 CSuplMoLrStateHandler* CSuplMoLrStateHandler::NewL(CSuplFsmSessionBase& aMachine) |
|
43 { |
|
44 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::NewL()\n"); |
|
45 CSuplMoLrStateHandler* self = new (ELeave) CSuplMoLrStateHandler(aMachine); |
|
46 return self; |
|
47 } |
|
48 |
|
49 /** Standard constructor. |
|
50 @param aMachine A reference to the parent state machine. |
|
51 */ |
|
52 CSuplMoLrStateHandler::CSuplMoLrStateHandler(CSuplFsmSessionBase& aMachine) |
|
53 : CSuplStateHandlerBase(aMachine) |
|
54 { |
|
55 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::CSuplMoLrStateHandler() Begin\n"); |
|
56 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::CSuplMoLrStateHandler() End\n"); |
|
57 } |
|
58 |
|
59 |
|
60 /** Standard destructor. |
|
61 */ |
|
62 CSuplMoLrStateHandler::~CSuplMoLrStateHandler() |
|
63 { |
|
64 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::~CSuplMoLrStateHandler() Begin\n"); |
|
65 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::~CSuplMoLrStateHandler() End\n"); |
|
66 } |
|
67 |
|
68 /** Perform entry actions. |
|
69 This is called from the state machine to perform any actions |
|
70 associated with entering the current state following an external |
|
71 event or an autonomous state transition. |
|
72 |
|
73 For some states, there is only one possible course of action. |
|
74 For other states, the event store has to be checked to see what |
|
75 events have occurred and what actions have to be taken to handle |
|
76 such events. |
|
77 |
|
78 If an event conductive to cancelling the state machine had occurred |
|
79 (e.g, an explicit client cancel, an error, or a timeout), then the |
|
80 state machine would have been set in an state that terminates the |
|
81 session before this method is called (either EStateSuplSessionEnded |
|
82 or EStatePosSessionEnded). |
|
83 |
|
84 @return TBool ETrue if any actions have been taken |
|
85 */ |
|
86 TBool CSuplMoLrStateHandler::EntryActionsL() |
|
87 { |
|
88 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsL() Begin\n"); |
|
89 TBool actionsTaken = ETrue; |
|
90 // Retrieve current state and act accordingly |
|
91 switch(iMachine.CurrentState()) |
|
92 { |
|
93 case CSuplFsmSessionBase::EStateProcedureNull: |
|
94 // No action |
|
95 break; |
|
96 |
|
97 case CSuplFsmSessionBase::EStateNetConnectionStarted: |
|
98 actionsTaken = EntryActionsFromNetConnectionStarted(); |
|
99 break; |
|
100 |
|
101 case CSuplFsmSessionBase::EStateStartSent: |
|
102 // Build and send a SUPL START message |
|
103 actionsTaken = EntryActionsFromStartSentStateL(); |
|
104 break; |
|
105 |
|
106 case CSuplFsmSessionBase::EStateResponseReceived: |
|
107 // Handle a received SUPL RESPONSE message |
|
108 actionsTaken = EntryActionsFromResponseReceivedStateL(); |
|
109 break; |
|
110 |
|
111 case CSuplFsmSessionBase::EStatePosInitSent: |
|
112 // Build and send a SUPL POS INIT |
|
113 actionsTaken = EntryActionsFromPosInitSentStateL(); |
|
114 break; |
|
115 |
|
116 case CSuplFsmSessionBase::EStatePositioningInProgress: |
|
117 actionsTaken = EntryActionsFromPositioningInProgressStateL(); |
|
118 break; |
|
119 |
|
120 case CSuplFsmSessionBase::EStatePositionReceived: |
|
121 actionsTaken = EntryActionsFromPositionReceivedStateL(); |
|
122 break; |
|
123 |
|
124 case CSuplFsmSessionBase::EStateSuplSessionEnded: |
|
125 // Send SUPL END |
|
126 actionsTaken = EntryActionsFromSuplSessionEndedStateL(); |
|
127 break; |
|
128 |
|
129 case CSuplFsmSessionBase::EStatePosSessionEnded: |
|
130 // Send to Positioning FSM an instruction to terminate silently |
|
131 // |
|
132 iMachine.PositioningFsm()->CancelMachine(CSuplPositioningProtocolFsm::ESuplFsmCancel, CSuplFsmSessionBase::EReasonNone); |
|
133 break; |
|
134 |
|
135 case CSuplFsmSessionBase::EStateLbsSessionEnded: |
|
136 // Send session complete indication to LBS |
|
137 actionsTaken = EntryActionsFromLbsSessionEndedStateL(); |
|
138 break; |
|
139 |
|
140 case CSuplFsmSessionBase::EStateNetConnectionClosed: |
|
141 // Close the network connection |
|
142 iMachine.CompleteProcedure(); |
|
143 break; |
|
144 |
|
145 default: |
|
146 ASSERT(EFalse); |
|
147 break; |
|
148 } |
|
149 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsL() End\n"); |
|
150 return actionsTaken; |
|
151 } |
|
152 //--------------------------------------------------------------------------------------------------------------------- |
|
153 // ----------------------- METHODS FOR ACTIONS AFTER ENTERING STATES --------------------------------------------- |
|
154 //--------------------------------------------------------------------------------------------------------------------- |
|
155 |
|
156 /** Actions on entering state EStateNetConnectionStarted |
|
157 |
|
158 This method obtains an SLP Id from the Host Settings store |
|
159 and asks the Connection Manager to provide a connection with it. |
|
160 */ |
|
161 TBool CSuplMoLrStateHandler::EntryActionsFromNetConnectionStarted() |
|
162 { |
|
163 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromNetConnectionStarted() Begin\n"); |
|
164 TLbsHostSettingsId hostId = TUid::Uid(0); |
|
165 TLbsNetSessionId::TSessionNum sessIdNum = 0; |
|
166 TInt err = iMachine.GetHostId(hostId); |
|
167 |
|
168 if (KErrNone == err) |
|
169 { |
|
170 // Request a connection from the Connection Manager |
|
171 // |
|
172 sessIdNum = iMachine.SessionId().SessionNum(); |
|
173 iMachine.Observer().ConnectionManager().Connect(sessIdNum, hostId, CSuplSessionRecord::EServiceMolr, iMachine); |
|
174 // start the timer that oversees connection creation |
|
175 iMachine.StartConnectionTimer(); |
|
176 } |
|
177 else |
|
178 { |
|
179 // Cancel session as a SUPL server could not be determined |
|
180 iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonSlpSettingsMissing); |
|
181 } |
|
182 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromNetConnectionStarted() End\n"); |
|
183 return ETrue; |
|
184 } |
|
185 |
|
186 /** Actions on entering state EStateStartSent |
|
187 |
|
188 This method builds a SUPL START and passes it on to |
|
189 the Connection Manager for sending to the SUPL server |
|
190 |
|
191 */ |
|
192 TBool CSuplMoLrStateHandler::EntryActionsFromStartSentStateL() |
|
193 { |
|
194 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromStartSentStateL() Begin\n"); |
|
195 |
|
196 TLbsNetPosRequestQuality quality; |
|
197 TLbsNetPosCapabilities capabilities; |
|
198 |
|
199 ASSERT(iMachine.IsSessionConnected()); // should not have transitioned into this state without a connection |
|
200 |
|
201 // A SUPL START message must contain a Location ID with |
|
202 // network information (cell ID, etc). If such data has |
|
203 // not been made available to the state machine then |
|
204 // cancel ongoing session |
|
205 CSuplLocationId* locationId ; |
|
206 if (BuildLocationIdL(locationId)) |
|
207 { |
|
208 CleanupStack::PushL(locationId); |
|
209 } |
|
210 else |
|
211 { |
|
212 iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonNone); |
|
213 return EFalse; |
|
214 } |
|
215 |
|
216 // Create a SUPL message common part. |
|
217 // Set the SET session ID only in CSuplSessionId. |
|
218 CSuplSessionId* sessionId = CSuplSessionId::NewL(); |
|
219 CleanupStack::PushL(sessionId); |
|
220 sessionId->iSetSessionIdPresent = ETrue; |
|
221 sessionId->iSetSessionId->iSessionId = iMachine.SessionId().SessionNum(); |
|
222 sessionId->iSetSessionId->iSetId->iSetIdType = ESuplSetIdTypeMsisdn; // TSuplSetIdType |
|
223 |
|
224 const TUint8 KMaxMsisdnLength = 8; |
|
225 TDes8& des = sessionId->iSetSessionId->iSetId->iSetId; |
|
226 if(iMachine.Msisdn()) |
|
227 { |
|
228 ConvertToBcd(des); |
|
229 } |
|
230 else |
|
231 { |
|
232 //Fill the descriptor with all bits set to 0, then append a 0xFF to the end to indicate the end of the MSISDN |
|
233 des.SetLength(KMaxMsisdnLength); |
|
234 des.Fill(0x00, (KMaxMsisdnLength -1)); //7 0's |
|
235 des.Append(0xFF); //Final 1 FF |
|
236 } |
|
237 |
|
238 //The commented code can be used when the set id type selection from the Host Settings API is implemented |
|
239 //TUint32 ipAddr = iMachine.RetrieveLocalIpAddress().Address(); |
|
240 //sessionId->iSetSessionId->iSetId->iIpAddress->iIpAddressType = ESuplIpAddressTypeV4; |
|
241 //sessionId->iSetSessionId->iSetId->iIpAddress->iIpAddress.Copy(reinterpret_cast<unsigned char*>(&ipAddr), 4); |
|
242 |
|
243 // Keep session Id for future reference |
|
244 iMachine.SetMessageSessionId(sessionId); // ownership transferred |
|
245 CleanupStack::Pop(sessionId); |
|
246 |
|
247 // positioning capabilities and request quality to be set in SUPL START |
|
248 // are built using the stored Request Options |
|
249 if (CSuplMolrFsmSession::ESuplMolrCellBased == (reinterpret_cast <CSuplMolrFsmSession&> (iMachine)).MachineType()) |
|
250 { |
|
251 TLbsNetPosRequestOptions locReqOptions; |
|
252 iMachine.RetrieveLocationRequestOptions(locReqOptions); |
|
253 |
|
254 TLbsNetPosMethod posMethods[1]; |
|
255 posMethods[0].SetPosMethod(KLbsPositioningMeansCell, TPositionModuleInfo::ETechnologyNetwork); |
|
256 capabilities.SetPosMethods(posMethods, 1); |
|
257 |
|
258 locReqOptions.GetRequestQuality(quality); |
|
259 } |
|
260 else // Not Cell-Based only |
|
261 { |
|
262 // Send all of LBS' capabilities in the SUPL START |
|
263 BuildCapabilitiesL(capabilities,quality); |
|
264 } |
|
265 |
|
266 // Create the SUPL START Message |
|
267 CSuplStart* suplStart = CSuplStart::NewLC(); |
|
268 TInt err = suplStart->SetCapabilities(capabilities); |
|
269 err = suplStart->SetLocationId(*locationId); |
|
270 err= suplStart->SetSessionId(*sessionId); |
|
271 err = suplStart->SetQoP(quality); |
|
272 |
|
273 CleanupStack::Pop(suplStart); |
|
274 CleanupStack::PopAndDestroy(locationId); |
|
275 |
|
276 // Ask the Connection Manager to send the SUPL START message to the server |
|
277 iMachine.Observer().ConnectionManager().SendMessage(suplStart, iMachine.SessionId().SessionNum()); |
|
278 |
|
279 iMachine.SetSessionInProgress(ETrue); |
|
280 |
|
281 // start the timer that oversees the arrival of SUPL RESPONSE |
|
282 (reinterpret_cast <CSuplMolrFsmSession&> (iMachine)).StartSuplResponseTimer(); |
|
283 |
|
284 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromStartSentStateL() End\n"); |
|
285 return ETrue; |
|
286 } |
|
287 |
|
288 /** Actions on entering state EStateResponseReceived |
|
289 |
|
290 This method extracts the positioning method from SUPL RESPONSE and |
|
291 sends a new location request to LBS. |
|
292 */ |
|
293 TBool CSuplMoLrStateHandler::EntryActionsFromResponseReceivedStateL() |
|
294 { |
|
295 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromResponseReceivedStateL() Begin\n"); |
|
296 TBool actionsTaken = EFalse; |
|
297 |
|
298 // A SUPL RESPONSE must be the oldest SUPL message in the |
|
299 // event store at this point. |
|
300 |
|
301 CSuplMessageBase* suplMessage = const_cast <CSuplMessageBase*> (iMachine.RetrieveSuplMessage()); |
|
302 |
|
303 ASSERT(suplMessage != NULL); |
|
304 ASSERT(CSuplMessageBase::ESuplResponse == suplMessage->MessageType()); |
|
305 |
|
306 if ((suplMessage != NULL) && (CSuplMessageBase::ESuplResponse == suplMessage->MessageType())) |
|
307 { |
|
308 CSuplResponse* responsePtr = static_cast <CSuplResponse*>(suplMessage); |
|
309 |
|
310 // Check that the SetId is the same that was sent in the SUPL START |
|
311 CSuplSessionId *sessId = CSuplSessionId::NewLC(); |
|
312 responsePtr->GetSessionId(*sessId); |
|
313 if (! ((*(iMachine.MessageSessionId()->iSetSessionId)) == (*(sessId->iSetSessionId)))) |
|
314 { |
|
315 iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonInvalidSessId); |
|
316 // Store received session Id for sending later in SUPL END as per SUPL specification |
|
317 CleanupStack::Pop(sessId); |
|
318 iMachine.SetMessageSessionId(sessId); // ownership transferred |
|
319 delete responsePtr; |
|
320 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromResponseReceivedStateL() End\n"); |
|
321 return actionsTaken; |
|
322 } |
|
323 else |
|
324 { |
|
325 CleanupStack::Pop(sessId); |
|
326 // Store received session Id for later use |
|
327 iMachine.SetMessageSessionId(sessId); // ownership transferred |
|
328 } |
|
329 |
|
330 // Extract the Positioning Method that SHALL (as per SUPL specification) |
|
331 // be used for the SUPL POS session |
|
332 TLbsNetPosRequestMethod posMethod; |
|
333 TLbsNetPosMethod selectedMethod; // only one to send to LBS |
|
334 TInt err = responsePtr->GetPosMethod(posMethod); |
|
335 TLbsNetPosCapabilities capabilities; |
|
336 iMachine.Observer().Gateway().GetCapabilities(capabilities); |
|
337 if ((KErrNone != err) || !iMachine.PosMethodSupported(posMethod, selectedMethod,capabilities)) |
|
338 { |
|
339 //Cancel with error code posMethodMistmach |
|
340 iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonMethodMismatch); |
|
341 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromResponseReceivedStateL() End\n"); |
|
342 delete responsePtr; |
|
343 return actionsTaken; |
|
344 } |
|
345 |
|
346 // send request to LBS |
|
347 if (CSuplMolrFsmSession::ESuplMolrCellBased != (reinterpret_cast <CSuplMolrFsmSession&> (iMachine)).MachineType()) |
|
348 { |
|
349 // Methods to be requested from LBS |
|
350 posMethod.SetPosMethods(&selectedMethod, 1); |
|
351 |
|
352 // Quality to be requested from LBS. The SUPL RESPONSE constains no quality requirements. |
|
353 // Use the quality originally requested by LBS |
|
354 TLbsNetPosRequestOptionsAssistance locReqAssistOptions; |
|
355 TLbsNetPosRequestQuality quality; |
|
356 iMachine.RetrieveLocationRequestOptions(locReqAssistOptions); |
|
357 locReqAssistOptions.GetRequestQuality(quality); |
|
358 |
|
359 iMachine.Observer().LocationReq(iMachine.LbsSessionId(), iMachine.LocReqType(), |
|
360 quality, posMethod); |
|
361 } |
|
362 |
|
363 delete responsePtr; |
|
364 actionsTaken = ETrue; |
|
365 } |
|
366 |
|
367 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromResponseReceivedStateL() End\n"); |
|
368 return actionsTaken; |
|
369 } |
|
370 |
|
371 |
|
372 /** Actions on entering state EStatePosInitSent |
|
373 This method builds a SUPL POS INIT message and hands it over to |
|
374 the Connection Manager for sending to the SUPL server. |
|
375 */ |
|
376 TBool CSuplMoLrStateHandler::EntryActionsFromPosInitSentStateL() |
|
377 { |
|
378 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromPosInitSentStateL() Begin\n"); |
|
379 TBool err = EFalse; |
|
380 TLbsNetPosRequestQuality quality; |
|
381 TLbsNetPosCapabilities capabilities; |
|
382 TBool actionsTaken = EFalse; |
|
383 |
|
384 // There should be an assistance data request from LBS in the event store |
|
385 // |
|
386 if (iMachine.IsAssistanceDataRequestStored()) |
|
387 { |
|
388 ASSERT(iMachine.IsSessionConnected()); // should not have transitioned into this state without a connection |
|
389 |
|
390 // Create the SUPL POS INIT Message |
|
391 CSuplPosInit* suplPosInit = CSuplPosInit::NewL(); |
|
392 CleanupStack::PushL(suplPosInit); |
|
393 |
|
394 // Set the Location Id in the message |
|
395 CSuplLocationId* locationId; |
|
396 if (BuildLocationIdL(locationId)) |
|
397 { |
|
398 CleanupStack::PushL(locationId); |
|
399 |
|
400 suplPosInit->SetLocationId(*locationId); |
|
401 CleanupStack::PopAndDestroy(locationId); |
|
402 |
|
403 // Set Capabilities in the message |
|
404 BuildCapabilitiesL(capabilities,quality); |
|
405 User::LeaveIfError(suplPosInit->SetCapabilities(capabilities)); |
|
406 |
|
407 // Set assistance data request in the message if any data |
|
408 // is actually required |
|
409 TLbsAsistanceDataGroup assitDataReqMask; |
|
410 TBool assitDataReqPresent = iMachine.RetrieveAssistanceDataRequest(assitDataReqMask); |
|
411 if (assitDataReqMask != 0) |
|
412 { |
|
413 User::LeaveIfError(suplPosInit->SetRequestedAssistanceData(assitDataReqMask)); |
|
414 } |
|
415 else |
|
416 { |
|
417 // No need to set assistance data request parameter |
|
418 // in SUPL POS INIT when request is empty. |
|
419 // (intentionally no action taken here) |
|
420 } |
|
421 |
|
422 // Set in message header the stored session id |
|
423 CSuplSessionId* msgId = iMachine.MessageSessionId(); |
|
424 User::LeaveIfError(suplPosInit->SetSessionId(*msgId)); |
|
425 |
|
426 CleanupStack::Pop(suplPosInit); |
|
427 |
|
428 // Ask the Connection Manager to send the SUPL POS INIT message |
|
429 iMachine.Observer().ConnectionManager().SendMessage(suplPosInit, iMachine.SessionId().SessionNum()); |
|
430 |
|
431 // Start the timer that oversees the arrival of SUPL POS |
|
432 iMachine.StartSuplPosTimer(); |
|
433 |
|
434 actionsTaken = ETrue; |
|
435 } |
|
436 else |
|
437 { |
|
438 // Failed to build Location Id |
|
439 err = ETrue; |
|
440 CleanupStack::PopAndDestroy(suplPosInit); |
|
441 } |
|
442 } |
|
443 else |
|
444 { |
|
445 // An unexpected event must have happened (e.g. SUPL Message received) |
|
446 // that triggered the transition to this state. |
|
447 err = ETrue; |
|
448 } |
|
449 |
|
450 if (err) |
|
451 { |
|
452 iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonNone); |
|
453 } |
|
454 |
|
455 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::EntryActionsFromPosInitSentStateL() End\n"); |
|
456 return actionsTaken; |
|
457 } |
|
458 |
|
459 /** |
|
460 Utility method that obtains the capabilities in the stored location request options |
|
461 and adds to them the preferred positioning method also stored in the location request |
|
462 option |
|
463 */ |
|
464 TBool CSuplMoLrStateHandler::BuildCapabilitiesL(TLbsNetPosCapabilities& aCapabilities, TLbsNetPosRequestQuality& aQuality) |
|
465 { |
|
466 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::BuildCapabilitiesL() Begin\n"); |
|
467 TLbsNetPosRequestOptionsAssistance locReqAssistOptions; |
|
468 TLbsNetPosMethod prefMethod; |
|
469 TInt numMethods; |
|
470 TInt index; |
|
471 TBool ecidSupported = EFalse; |
|
472 TInt additionalMethods = 0; |
|
473 |
|
474 // The positioning method preferred by LBS was sent in the call to |
|
475 // RequestSelfLocation and was kept in the event store. |
|
476 iMachine.Observer().Gateway().GetCapabilities(aCapabilities); |
|
477 numMethods = aCapabilities.NumPosMethods(); |
|
478 iMachine.RetrieveLocationRequestOptions(locReqAssistOptions); |
|
479 prefMethod.SetPosMethod(KLbsPositioningMeansGps, locReqAssistOptions.PosMode()); |
|
480 additionalMethods ++; |
|
481 |
|
482 // Check if E-CID is possible |
|
483 // (currently this mean Timing Advance only) |
|
484 if(iMachine.IsNetworkInfoAvailable()) |
|
485 { |
|
486 RMobilePhone::TMobilePhoneNetworkInfoV1 networkInfo; |
|
487 RMobilePhone::TMobilePhoneLocationAreaV1 locationArea; |
|
488 iMachine.RetrieveStoredNetworkInfo(networkInfo, locationArea); |
|
489 if (RMobilePhone::ENetworkModeGsm == networkInfo.iMode) |
|
490 { |
|
491 RMobilePhone::TMobilePhoneCellInfoV9 cellInfo; |
|
492 if(iMachine.RetrieveStoredCellInfo(cellInfo)) |
|
493 { |
|
494 // Timing Advance not supported if negative |
|
495 ecidSupported = (cellInfo.iTimingAdvance >= 0); |
|
496 additionalMethods++; |
|
497 } |
|
498 } |
|
499 } |
|
500 |
|
501 // The preferred method has to be added at the end of the array of methods in "capabilities" |
|
502 // because that is where the ASN1 encoder expects it to be. |
|
503 // If E-CID is supported and there is room for it in the array, it will also be added to the |
|
504 // array. |
|
505 TLbsNetPosMethod* methods; |
|
506 if (numMethods + additionalMethods < KLbsMaxNetPosMethods) |
|
507 { |
|
508 TLbsNetPosMethod ecidMethod; |
|
509 ecidMethod.SetPosMethod(KLbsPositioningMeansCell, TPositionModuleInfo::ETechnologyNetwork); |
|
510 methods = new (ELeave) TLbsNetPosMethod[numMethods + additionalMethods]; |
|
511 |
|
512 for (index =0; index < numMethods; index++) |
|
513 { |
|
514 aCapabilities.GetPosMethod(index, methods[index]); |
|
515 } |
|
516 |
|
517 if (ecidSupported) |
|
518 { |
|
519 methods[numMethods] = ecidMethod; |
|
520 } |
|
521 |
|
522 // Add preferred method at the end |
|
523 methods[numMethods + additionalMethods - 1] = prefMethod; |
|
524 aCapabilities.SetPosMethods(methods, numMethods + additionalMethods); |
|
525 } |
|
526 else |
|
527 { |
|
528 // There is only additional room for 1 or 0 methods. |
|
529 methods = new (ELeave) TLbsNetPosMethod[KLbsMaxNetPosMethods]; |
|
530 |
|
531 for (index =0; index < KLbsMaxNetPosMethods; index++) |
|
532 { |
|
533 aCapabilities.GetPosMethod(index, methods[index]); |
|
534 } |
|
535 |
|
536 // Set the preferred method at the end (even if it |
|
537 // overwrites current entry) |
|
538 methods[KLbsMaxNetPosMethods-1] = prefMethod; |
|
539 aCapabilities.SetPosMethods(methods, KLbsMaxNetPosMethods); |
|
540 } |
|
541 |
|
542 delete[] methods; |
|
543 locReqAssistOptions.GetRequestQuality(aQuality); |
|
544 |
|
545 SUPLLOG(ELogP1, "CSuplMoLrStateHandler::BuildCapabilitiesL() End\n"); |
|
546 return ETrue; |
|
547 } |
|
548 |