|
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 // @file ctlbsassdatastepmain.cpp |
|
15 // This is the class implementation for the Module Information Tests |
|
16 // EPOC includes. |
|
17 // |
|
18 // |
|
19 |
|
20 // LBS includes. |
|
21 #include <lbs.h> |
|
22 #include <lbs/lbsnetcommon.h> |
|
23 #include <lbssatellite.h> |
|
24 #include <lbs/lbsnetprotocolbase.h> |
|
25 #include <lbs/lbsassistancedatabuilderset.h> |
|
26 |
|
27 // LBS test includes. |
|
28 #include "ctlbsassdatastepmain.h" |
|
29 #include <lbs/test/tlbsutils.h> |
|
30 |
|
31 |
|
32 const TInt KAssistanceDataProviderPluginUidValue = 0x10281D77; |
|
33 |
|
34 |
|
35 /** |
|
36 Static Constructor |
|
37 */ |
|
38 CT_LbsAssDataStep_Main* CT_LbsAssDataStep_Main::New(CT_LbsAssDataServer& aParent) |
|
39 { |
|
40 // Note the lack of ELeave. |
|
41 // This means that having insufficient memory will return NULL; |
|
42 CT_LbsAssDataStep_Main* testStep = new CT_LbsAssDataStep_Main(aParent); |
|
43 if (testStep) |
|
44 { |
|
45 TInt err = KErrNone; |
|
46 |
|
47 TRAP(err, testStep->ConstructL()); |
|
48 if (err) |
|
49 { |
|
50 delete testStep; |
|
51 testStep = NULL; |
|
52 } |
|
53 } |
|
54 return testStep; |
|
55 } |
|
56 |
|
57 |
|
58 /** |
|
59 * Constructor |
|
60 */ |
|
61 CT_LbsAssDataStep_Main::CT_LbsAssDataStep_Main(CT_LbsAssDataServer& aParent) : CT_LbsAssDataStep(aParent) |
|
62 { |
|
63 SetTestStepName(KLbsAssDataStep_Main); |
|
64 } |
|
65 |
|
66 void CT_LbsAssDataStep_Main::ConstructL() |
|
67 { |
|
68 // Create the base class objects. |
|
69 CT_LbsAssDataStep::ConstructL(); |
|
70 |
|
71 // and the active object wrapper for the notify position update. |
|
72 iDoPosUpdate = CT_LbsDoPosUpdate::NewL(this); |
|
73 |
|
74 // Create and start the module data bus monitor, to listen for incoming data. |
|
75 iModuleDataBusMonitor = CT_LbsAssDataModuleDataBusMonitor::NewL(this); |
|
76 |
|
77 // Create the privacy controller for the MT-LR. |
|
78 iPrivacyController = CLbsPrivacyController::NewL(*this); |
|
79 } |
|
80 |
|
81 /** |
|
82 * Destructor |
|
83 */ |
|
84 CT_LbsAssDataStep_Main::~CT_LbsAssDataStep_Main() |
|
85 { |
|
86 iDoPosUpdate->Cancel(); |
|
87 delete iDoPosUpdate; |
|
88 |
|
89 iModuleDataBusMonitor->Cancel(); |
|
90 delete iModuleDataBusMonitor; |
|
91 |
|
92 iPrivacyController->CancelNetworkLocationRequest(0); |
|
93 delete iPrivacyController; |
|
94 } |
|
95 |
|
96 /** |
|
97 * @return - TVerdict code |
|
98 * Override of base class pure virtual |
|
99 * Our implementation only gets called if the base class doTestStepPreambleL() did |
|
100 * not leave. That being the case, the current test result value will be EPass. |
|
101 */ |
|
102 TVerdict CT_LbsAssDataStep_Main::doTestStepL() |
|
103 { |
|
104 // Generic test step used to test the LBS Client Notify position update API. |
|
105 INFO_PRINTF1(_L(">>CT_LbsAssDataStep_Main::doTestStepL()")); |
|
106 |
|
107 if (TestStepResult() == EPass) |
|
108 { |
|
109 // Carry out common test actions (such as connecting to a server). |
|
110 T_LbsUtils utils; |
|
111 TModuleDataIn modDataIn; // Used to send test information to the test module. |
|
112 |
|
113 // Request type is module test mode and most tests will only expect |
|
114 // a single assistance data event. |
|
115 modDataIn.iRequestType = TModuleDataIn::EModuleRequestTestMode; |
|
116 modDataIn.iAssDataEventType = TModuleDataIn::EAssDataEventExpectSingle; |
|
117 |
|
118 // Expected callbacks flags, most test steps require MO-LR. |
|
119 iFlagsToHaltOn = KLbsCallback_NetSim_Got_Connect | // Net Sim callback events. |
|
120 KLbsCallback_MoLr | |
|
121 KLbsCallback_Got_NotifyUpdate | // Test case callback events. |
|
122 KLbsCallback_Got_ModuleAssDataAnswer; // Test module returned an answer. |
|
123 |
|
124 // Carry out unique test actions. |
|
125 if (GetIntFromConfig(ConfigSection(), KTestCaseId, iTestCaseId)) |
|
126 { |
|
127 switch (iTestCaseId) |
|
128 { |
|
129 // Test case LBS-Ass-Data-0001 |
|
130 case 1: |
|
131 { |
|
132 // Test case LBS-Ass-Data-0001 - A-GPS module creation and destruction. |
|
133 |
|
134 // TODO: Require a method of shuting down Lbs. |
|
135 } |
|
136 break; |
|
137 |
|
138 |
|
139 // Test case LBS-Ass-Data-0010 - Verify a single batch of GPS assistance data. |
|
140 // |
|
141 // External step: Create verify position for MO-LR. |
|
142 // Local step: Inform module of required assistance data test mode. |
|
143 // Setup net sim assistance data. |
|
144 // Do MO-LR. |
|
145 // Module: Request assistance data. |
|
146 // Read and verify assistance data and inform test step, ensure correct number of events. |
|
147 // Local callback: Verify assistance data ok response. |
|
148 // External step: Verify the position info data. |
|
149 case 10: |
|
150 { |
|
151 // Set the test mode of the test module. |
|
152 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn; |
|
153 } |
|
154 break; |
|
155 |
|
156 |
|
157 // Test case LBS-Ass-Data-0011 - Verify multiple batches of GPS assistance data. |
|
158 // |
|
159 // External step: Create verify position for MO-LR. |
|
160 // Local step: Inform module of required multiple assistance data events test mode. |
|
161 // Setup net sim assistance data. |
|
162 // Do MO-LR. |
|
163 // Module: Request assistance data. |
|
164 // Read and verify assistance data, ensure correct number of events. |
|
165 // Local callback: Verify assistance data ok response. |
|
166 // External step: Verify the position info data. |
|
167 |
|
168 // TODO: May not be possible to pass assist data which causes multi events, also test 42 does some similar. |
|
169 case 11: |
|
170 |
|
171 |
|
172 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
173 // |
|
174 // External step: Create verify position for MO-LR. |
|
175 // Local step: Inform module of required assistance data test mode. |
|
176 // Setup net sim assistance data. |
|
177 // Do MO-LR |
|
178 // Module: Start assistance data request. |
|
179 // Cancel assistance data request - invoked via register callback. |
|
180 // Local callback: Ensure the KErrCancel is returned for ReleaseLcsMoLr callback. |
|
181 // Verify cancel request was recived by the module. |
|
182 // Verify assistance data cancelled ok response. |
|
183 // External step: Verify the position info data. |
|
184 case 12: |
|
185 { |
|
186 // Expected callbacks flags, for a assitance data cancel during a MO-LR. |
|
187 // |
|
188 // Note: Currently we get a module answer because the assistance data event |
|
189 // function is still called within the module - this may not happen if the |
|
190 // timing of the cancel is different on other environments. |
|
191 iFlagsToHaltOn = KLbsCallback_NetSim_Got_Connect | // Net Sim callback events. |
|
192 |
|
193 KLbsCallback_NetSim_Got_NotifyRegisterLcsMoLr | |
|
194 KLbsCallback_NetSim_Got_NotifyReleaseLcsMoLr | |
|
195 |
|
196 KLbsCallback_Got_NotifyUpdate | // Test case callback events. |
|
197 KLbsCallback_Got_ModuleAssDataAnswer; // Test module returned an answer. |
|
198 |
|
199 // Set the test mode of the test module. |
|
200 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_Cancel_Stage1; |
|
201 } |
|
202 break; |
|
203 |
|
204 |
|
205 // Test case LBS-Ass-Data-0020 - Verify unsolicited GPS assistance data. |
|
206 // |
|
207 // External step: Create position for MT-LR. |
|
208 // Local step: Inform module of required single ass data event, and unsolicited test. |
|
209 // Setup net sim assistance data. |
|
210 // Do MT-LR |
|
211 // Module: Read and verify ass data, ensure correct number of events. |
|
212 // Local callback: Verify ass data ok response from module. |
|
213 case 20: |
|
214 { |
|
215 // Expected callbacks flags for this test step. |
|
216 iFlagsToHaltOn = KLbsCallback_NetSim_Got_Connect | // Net Sim callback events. |
|
217 KLbsCallback_MtLr | |
|
218 KLbsCallback_Got_ModuleAssDataAnswer; // Test module returned an answer. |
|
219 |
|
220 // Setup emergency locate service and pause to ensure value is set. |
|
221 CLbsAdmin* admin = CLbsAdmin::NewL(); |
|
222 User::LeaveIfError(admin->Set(KLbsSettingHomeEmergencyLocate, CLbsAdmin::EExternalLocateOn)); |
|
223 User::After(10000000); |
|
224 |
|
225 delete admin; |
|
226 |
|
227 // Set the test mode of the test module. |
|
228 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_Unsolicited; |
|
229 } |
|
230 break; |
|
231 |
|
232 |
|
233 // Test case LBS-Ass-Data-0030 - Verify the GPS assistance data time stamp. |
|
234 // |
|
235 // External step: Create verify position for MO-LR. |
|
236 // Local step: Inform module of required assistance data test mode. |
|
237 // Setup net sim assistance data. |
|
238 // Do MO-LR. |
|
239 // Module: Read and verify assistance data, ensure correct number of events, |
|
240 // and verify timestamp. |
|
241 // Local callback: Verify assistance data ok response. |
|
242 // External step: Verify the position info data. |
|
243 case 30: |
|
244 { |
|
245 // Set the test mode of the test module. |
|
246 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_TimeStamp; |
|
247 } |
|
248 break; |
|
249 |
|
250 |
|
251 // Test case LBS-Ass-Data-0040 - Empty GPS assistance data cache test. |
|
252 // |
|
253 // External step: Create verify position for MO-LR. |
|
254 // Local step: Inform module of required assistance data test mode. |
|
255 // Setup net sim assistance data. |
|
256 // Do MO-LR. |
|
257 // Module: Attempt to read assistance data before receiving assistance data |
|
258 // event, and verify KErrNotFound is returned, and inform test step. |
|
259 // Local callback: Verify assistance data test ok response. |
|
260 // External step: Verify the position info data. |
|
261 case 40: |
|
262 { |
|
263 // Expected callbacks flags, not asking for assitance data so not expecting any MO-LR callbacks. |
|
264 iFlagsToHaltOn = KLbsCallback_NetSim_Got_Connect | // Net Sim callback events. |
|
265 |
|
266 KLbsCallback_Got_NotifyUpdate | // Test case callback events. |
|
267 KLbsCallback_Got_ModuleAssDataAnswer; // Test module returned an answer. |
|
268 |
|
269 // Set the test mode of the test module. |
|
270 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_DataNotAvailable; |
|
271 } |
|
272 break; |
|
273 |
|
274 |
|
275 // Test case LBS-Ass-Data-0041 - Request GPS assistance data when no network available. |
|
276 // |
|
277 // External step: Create verify position for MO-LR. |
|
278 // Local step: Inform module of required assistance data test mode. |
|
279 // Setup net sim assistance data. |
|
280 // Do MO-LR. |
|
281 // Module: Request assistance data, ensure KErrNotReady is return when the |
|
282 // data event is fired. |
|
283 // Local callback: Verify assistance data ok response. |
|
284 // External step: Verify the position info data. |
|
285 case 41: |
|
286 { |
|
287 // Expected callbacks flags, expect the assistance request to fail so not expecting any MO-LR callbacks. |
|
288 iFlagsToHaltOn = KLbsCallback_NetSim_Got_Connect | // Net Sim callback events. |
|
289 |
|
290 KLbsCallback_Got_NotifyUpdate | // Test case callback events. |
|
291 KLbsCallback_Got_ModuleAssDataAnswer; // Test module returned an answer. |
|
292 |
|
293 // Set the test mode of the test module. |
|
294 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_NoNetwork; |
|
295 } |
|
296 break; |
|
297 |
|
298 |
|
299 // Test case LBS-Ass-Data-0042 - Request multiple items of GPS assistance data when not all of the itmes are available. |
|
300 // |
|
301 // External step: Create verify position for MO-LR. |
|
302 // Local step: Inform module of required assistance data test mode. |
|
303 // Setup net sim assistance data, to return 1 item of data. |
|
304 // Do MO-LR. |
|
305 // Module: Request 2 items of assistance data, ensure item 1 is deliveried, item 2 returns an error |
|
306 // of KErrNotFound. |
|
307 // Local callback: Verify assistance data ok response, for both data items. |
|
308 // External step: Verify the position info data. |
|
309 case 42: |
|
310 { |
|
311 // Add the expected MeasurementReportRequestMoreAssistanceData flag. |
|
312 iFlagsToHaltOn |= KLbsCallback_NetSim_Got_NotifyMeasurementReportRequestMoreAssistanceData; |
|
313 |
|
314 |
|
315 // Set the test mode of the test module. |
|
316 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_SomeDataNotAvailable; |
|
317 } |
|
318 break; |
|
319 |
|
320 |
|
321 // Test case LBS-Ass-Data-0050 - Request assistance data, upper boundary test. |
|
322 // |
|
323 // External step: Create verify position for MO-LR. |
|
324 // Local step: Inform module of required assistance data test mode. |
|
325 // Setup net sim assistance data. |
|
326 // Do MO-LR. |
|
327 // Module: Request non-exsisting type of assistance data, ensure the data event is fired with |
|
328 // a error of KErrArgument. |
|
329 // Local callback: Verify assistance data ok response. |
|
330 // External step: Verify the position info data. |
|
331 case 50: |
|
332 { |
|
333 // Set the test mode of the test module. |
|
334 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_InvalidDataRequest; |
|
335 } |
|
336 break; |
|
337 |
|
338 // Test case LBS-Ass-Data-0051 - Get assistance data item, upper boundary test. |
|
339 // |
|
340 // External step: Create verify position for MO-LR. |
|
341 // Local step: Inform module of required assistance data test mode. |
|
342 // Setup net sim assistance data. |
|
343 // Do MO-LR. |
|
344 // Module: Request assistance data. |
|
345 // From the event callback attempt to get assistance data using a invalid mask, |
|
346 // ensure the error of KErrNotFound is returned. |
|
347 // Local callback: Verify assistance data ok response. |
|
348 // External step: Verify the position info data. |
|
349 case 51: |
|
350 { |
|
351 // Set the test mode of the test module. |
|
352 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_InvalidDataGet; |
|
353 } |
|
354 break; |
|
355 |
|
356 |
|
357 default: |
|
358 { |
|
359 User::Panic(KLbsAssDataStep_Main, KErrUnknown); |
|
360 } |
|
361 } |
|
362 } |
|
363 |
|
364 |
|
365 // Carry out the test. |
|
366 |
|
367 // Inform the test module of the required test mode - will block. |
|
368 utils.NotifyModuleOfConfigChangeL(modDataIn); |
|
369 |
|
370 // Connect to net sim. |
|
371 iNetSim.ConnectL(this); |
|
372 |
|
373 // Setup net sim's assistance data. |
|
374 |
|
375 // some tests doesn't need ref loc |
|
376 switch (iTestCaseId) |
|
377 { |
|
378 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
379 case 12: |
|
380 // Test case LBS-Ass-Data-0040 - Empty GPS assistance data cache test. |
|
381 case 40: |
|
382 // Test case LBS-Ass-Data-0041 - Request GPS assistance data when no network available. |
|
383 case 41: |
|
384 { |
|
385 // Do nothing. |
|
386 } |
|
387 break; |
|
388 default: |
|
389 { |
|
390 // Create a refposinfo and store in our shared array for later verification. |
|
391 RPointerArray<TAny>& refposInfoArr = iParent.iSharedData->iVerifyPosInfoArr; |
|
392 TPositionInfo* refposinfo = reinterpret_cast<TPositionInfo*>(refposInfoArr[1]); |
|
393 TPosition pos; |
|
394 refposinfo->GetPosition(pos); |
|
395 |
|
396 if (!iNetSim.SetReferenceLocation(pos)) |
|
397 { |
|
398 INFO_PRINTF1(_L("Failed test, can't set NetSim's reference location.")); |
|
399 SetTestStepResult(EFail); |
|
400 |
|
401 iNetSim.Close(); |
|
402 |
|
403 return TestStepResult(); |
|
404 } |
|
405 |
|
406 // Set the position quality required by the network. |
|
407 TTimeIntervalMicroSeconds maxFixTime(55000000); |
|
408 TLbsNetPosRequestQuality netPosQuality; |
|
409 |
|
410 netPosQuality.SetMaxFixTime(maxFixTime); |
|
411 netPosQuality.SetMinHorizontalAccuracy(6.6); |
|
412 netPosQuality.SetMinVerticalAccuracy(7.7); |
|
413 |
|
414 if (!iNetSim.SetQuality(netPosQuality)) |
|
415 { |
|
416 INFO_PRINTF1(_L("Failed test, can't set NetSim's quality.")); |
|
417 SetTestStepResult(EFail); |
|
418 |
|
419 iNetSim.Close(); |
|
420 |
|
421 return TestStepResult(); |
|
422 } |
|
423 |
|
424 } |
|
425 } |
|
426 // Set plugin to use. |
|
427 TUid pluginUid = TUid::Uid(KAssistanceDataProviderPluginUidValue); |
|
428 if (!iNetSim.SetAssistanceDataProvider(pluginUid)) |
|
429 { |
|
430 INFO_PRINTF1(_L("Failed test, can't set NetSim's assistance data plugin uid.")); |
|
431 SetTestStepResult(EFail); |
|
432 |
|
433 iNetSim.Close(); |
|
434 |
|
435 return TestStepResult(); |
|
436 } |
|
437 |
|
438 // Start monitoring the module data bus, to retrieve assistance data verification |
|
439 // from the test module. |
|
440 iModuleDataBusMonitor->StartMonitorL(); |
|
441 |
|
442 |
|
443 // Kick off the keep alive timer. |
|
444 TTimeIntervalMicroSeconds32 interval(KLbsKeepAlivePeriod); |
|
445 |
|
446 iKeepAliveTimer->SetTimer(interval); |
|
447 |
|
448 // Kick off test. |
|
449 CActiveScheduler::Start(); |
|
450 |
|
451 |
|
452 // Clean up. |
|
453 iNetSim.ClearAssistanceDataFilters(); |
|
454 iNetSim.Close(); |
|
455 } |
|
456 |
|
457 INFO_PRINTF1(_L("<<CT_LbsAssDataStep_Main::doTestStepL()")); |
|
458 |
|
459 return TestStepResult(); |
|
460 } |
|
461 |
|
462 /** NetSim callbacks given for a MoLr, which we invoke as a result of the notify position update. |
|
463 */ |
|
464 void CT_LbsAssDataStep_Main::Connected() |
|
465 { |
|
466 // Call base implementation. |
|
467 CT_LbsNetSimStep::Connected(); |
|
468 |
|
469 switch (iTestCaseId) |
|
470 { |
|
471 // Test case LBS-Ass-Data-0020 - Verify unsolicited GPS assistance data. |
|
472 case 20: |
|
473 { |
|
474 // Start a MT-LR request. |
|
475 _LIT8(KTestRequesterId, "LbsAssData test requester id"); |
|
476 _LIT8(KTestClientName, "LbsAssData test client name"); |
|
477 _LIT8(KTestClientExternalId, "LbsAssData test client external id"); |
|
478 |
|
479 TLbsExternalRequestInfo reqInfo; |
|
480 reqInfo.SetRequesterId(KTestRequesterId); |
|
481 reqInfo.SetClientName(KTestClientName); |
|
482 reqInfo.SetClientExternalId(KTestClientExternalId); |
|
483 |
|
484 TLbsNetPosRequestPrivacy reqType; |
|
485 reqType.SetRequestAction(TLbsNetPosRequestPrivacy::ERequestActionAllow); |
|
486 reqType.SetRequestAdvice(TLbsNetPosRequestPrivacy::ERequestAdviceNotify); |
|
487 |
|
488 iNetSim.SetEmergenyStatus(ETrue); |
|
489 |
|
490 // kick off the privacy request: |
|
491 iNetSim.StartNetworkPrivacyRequest(reqType, reqInfo); |
|
492 |
|
493 iState = EStartMTLRPrivReq; |
|
494 } |
|
495 break; |
|
496 |
|
497 // Test case LBS-Ass-Data-0041 - Request GPS assistance data when no network available. |
|
498 case 41: |
|
499 |
|
500 if (!iNetSim.SetResponseError(RLbsNetSimTest::KNetSimNetworkNotAvailable, ETrue)) |
|
501 { |
|
502 INFO_PRINTF1(_L("Failed test, can't set NetSim's response code.")); |
|
503 SetTestStepResult(EFail); |
|
504 } |
|
505 |
|
506 // All other test cases required a MO-LR. |
|
507 default: |
|
508 { |
|
509 // Set net sim response code to KErrNone. |
|
510 if (iTestCaseId != 41) |
|
511 { |
|
512 if (!iNetSim.SetResponseError(KErrNone, ETrue)) |
|
513 { |
|
514 INFO_PRINTF1(_L("Failed test, can't set NetSim's response code.")); |
|
515 SetTestStepResult(EFail); |
|
516 } |
|
517 } |
|
518 |
|
519 // Create a posinfo and store in our shared array for later verification. |
|
520 RPointerArray<TAny>& posInfoArr = iParent.iSharedData->iCurrentPosInfoArr; |
|
521 TPositionInfo* posInfo = new(ELeave) TPositionInfo(); |
|
522 |
|
523 T_LbsUtils utils; |
|
524 utils.ResetAndDestroy_PosInfoArr(posInfoArr); // Clear previous entries before new entry is appended. |
|
525 |
|
526 posInfoArr.Append(posInfo); |
|
527 |
|
528 // Kick off pos update - this will invoke the assistance data processing |
|
529 // within the test module. The result of this will be reported back to |
|
530 // the test step via the module data bus monitor. |
|
531 iDoPosUpdate->StartL(*posInfo); |
|
532 |
|
533 // Move to the first pos update state after kick off first pos update |
|
534 iState = EFirstPosUpdate; |
|
535 } |
|
536 } |
|
537 } |
|
538 |
|
539 void CT_LbsAssDataStep_Main::Disconnected() |
|
540 { |
|
541 // Call base implementation. |
|
542 CT_LbsNetSimStep::Disconnected(); |
|
543 } |
|
544 |
|
545 |
|
546 void CT_LbsAssDataStep_Main::NotifyRegisterLcsMoLr(const TDesC& aData) |
|
547 { |
|
548 // Call base implementation. |
|
549 CT_LbsNetSimStep::NotifyRegisterLcsMoLr(aData); |
|
550 |
|
551 // Verify the aData is blank to indicate this is a MOLR. |
|
552 if (aData != KNullDesC) |
|
553 { |
|
554 INFO_PRINTF1(_L("Failed test, register contains data.")); |
|
555 SetTestStepResult(EFail); |
|
556 } |
|
557 |
|
558 switch (iTestCaseId) |
|
559 { |
|
560 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
561 case 12: |
|
562 { |
|
563 TModuleDataIn modDataIn; // Used to send test information to the test module. |
|
564 |
|
565 // Request type is module test mode and most tests will only expect |
|
566 // a single assistance data event. |
|
567 modDataIn.iRequestType = TModuleDataIn::EModuleRequestTestMode; |
|
568 |
|
569 // Inform the module it should perform the second part of the cancel test. |
|
570 modDataIn.iAssDataTestMode = TModuleDataIn::EModuleTestModeAssDataOn_Cancel_Stage2; |
|
571 |
|
572 // Inform the test module of the required test mode - will block. |
|
573 T_LbsUtils utils; |
|
574 |
|
575 utils.NotifyModuleOfConfigChangeL(modDataIn); |
|
576 } |
|
577 } |
|
578 } |
|
579 |
|
580 |
|
581 void CT_LbsAssDataStep_Main::NotifyReleaseLcsMoLr(TInt aReason) |
|
582 { |
|
583 // Call base implementation. |
|
584 CT_LbsNetSimStep::NotifyReleaseLcsMoLr(aReason); |
|
585 |
|
586 switch (iTestCaseId) |
|
587 { |
|
588 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
589 case 12: |
|
590 { |
|
591 if (aReason != KErrCancel) |
|
592 { |
|
593 INFO_PRINTF2(_L("Failed test, incorrect reason code expecting KErrCancel, got %d."), aReason); |
|
594 |
|
595 SetTestStepResult(EFail); |
|
596 } |
|
597 } |
|
598 break; |
|
599 |
|
600 default: |
|
601 { |
|
602 if (aReason != KErrNone) |
|
603 { |
|
604 INFO_PRINTF2(_L("Failed test, bad release reason %d."), aReason); |
|
605 SetTestStepResult(EFail); |
|
606 } |
|
607 } |
|
608 } |
|
609 } |
|
610 |
|
611 |
|
612 void CT_LbsAssDataStep_Main::NotifyMeasurementControlLocation(const TPositionInfo& aPosition, |
|
613 const RLbsAssistanceDataBuilderSet& aData, |
|
614 const TLbsNetPosRequestQuality& aQuality) |
|
615 { |
|
616 T_LbsUtils utils; |
|
617 TInt err; |
|
618 |
|
619 // Call base implementation. |
|
620 CT_LbsNetSimStep::NotifyMeasurementControlLocation(aPosition, aData, aQuality); |
|
621 |
|
622 // Verify the reference position - use the entry in the verify pos info array. |
|
623 RPointerArray<TAny>& verifyPosInfoArr = iParent.iSharedData->iVerifyPosInfoArr; |
|
624 TPositionInfo* verifyPosInfo = reinterpret_cast<TPositionInfo*>(verifyPosInfoArr[1]); |
|
625 if (!utils.Compare_PosInfo(* verifyPosInfo, aPosition)) |
|
626 { |
|
627 INFO_PRINTF1(_L("Failed test, position incorrect.")); |
|
628 SetTestStepResult(EFail); |
|
629 } |
|
630 |
|
631 // Verify the assistance data. |
|
632 RLbsAssistanceDataBuilderSet& data = const_cast<RLbsAssistanceDataBuilderSet&>(aData); |
|
633 RUEPositioningGpsReferenceTimeBuilder* refTimeBuilder = NULL; |
|
634 |
|
635 data.GetDataBuilder(refTimeBuilder); |
|
636 |
|
637 // Create a reader from the builder's data to allow us to verify the actual |
|
638 // assistance data. |
|
639 RUEPositioningGpsReferenceTimeReader refTimeReader; |
|
640 |
|
641 TRAP(err, refTimeReader.OpenL()); |
|
642 if (err == KErrNone) |
|
643 { |
|
644 refTimeReader.DataBuffer() = refTimeBuilder->DataBuffer(); |
|
645 |
|
646 if (!utils.VerifySimpleAssistanceData(refTimeReader)) |
|
647 { |
|
648 INFO_PRINTF1(_L("Failed test, assistance data incorrect.")); |
|
649 SetTestStepResult(EFail); |
|
650 } |
|
651 refTimeReader.Close(); |
|
652 } |
|
653 |
|
654 else |
|
655 { |
|
656 INFO_PRINTF2(_L("Failed test, assistance data reader err %d."), err); |
|
657 SetTestStepResult(EFail); |
|
658 } |
|
659 |
|
660 |
|
661 |
|
662 // TODO: Check if we can verify aQuality in any way. |
|
663 (void)aQuality; |
|
664 } |
|
665 |
|
666 |
|
667 void CT_LbsAssDataStep_Main::NotifyReleaseLcsLocationNotification(const CLbsNetworkProtocolBase::TLbsPrivacyResponse& aResult) |
|
668 { |
|
669 // Call base implementation. |
|
670 CT_LbsNetSimStep::NotifyReleaseLcsLocationNotification(aResult); |
|
671 |
|
672 |
|
673 // We should get this callback if requesting a MT-LR. |
|
674 ASSERT(iState == EStartMTLRPrivReq); |
|
675 |
|
676 // Should allways except privacy requests. |
|
677 if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted == aResult) |
|
678 { |
|
679 // Now invoke MT-LR location request. |
|
680 iNetSim.StartNetworkLocationRequest(); |
|
681 |
|
682 iState = EStartMTLRLocReq; |
|
683 } |
|
684 |
|
685 // Un-expected response. |
|
686 else |
|
687 { |
|
688 INFO_PRINTF1(_L("Failed test, should have excepted MT-LR privacy request.")); |
|
689 SetTestStepResult(EFail); |
|
690 } |
|
691 } |
|
692 |
|
693 |
|
694 void CT_LbsAssDataStep_Main::NotifyFacilityLcsMoLrResult(TInt aReason, const TPositionInfo& aPosition) |
|
695 { |
|
696 // Call base implementation. |
|
697 CT_LbsNetSimStep::NotifyFacilityLcsMoLrResult(aReason, aPosition); |
|
698 |
|
699 if (aReason != KErrNone) |
|
700 { |
|
701 INFO_PRINTF2(_L("Failed test, bad release reason %d."), aReason); |
|
702 SetTestStepResult(EFail); |
|
703 } |
|
704 |
|
705 |
|
706 // Verify the real position returned from the network, this will be the same position |
|
707 // we sent to the network as the result of the MO-LR, thus use the entry given by |
|
708 // the test module. |
|
709 T_LbsUtils utils; |
|
710 RPointerArray<TAny>& verifyPosInfoArr = iParent.iSharedData->iVerifyPosInfoArr; |
|
711 TPositionInfo* verifyRealPosInfo = reinterpret_cast<TPositionInfo*>(verifyPosInfoArr[0]); |
|
712 if (!utils.Compare_PosInfo(*verifyRealPosInfo, aPosition)) |
|
713 { |
|
714 INFO_PRINTF1(_L("Failed test, position incorrect.")); |
|
715 SetTestStepResult(EFail); |
|
716 } |
|
717 } |
|
718 |
|
719 void CT_LbsAssDataStep_Main::NotifyMeasurementReportLocation(const TPositionInfo& aPosition) |
|
720 { |
|
721 // Call base implementation. |
|
722 CT_LbsNetSimStep::NotifyMeasurementReportLocation(aPosition); |
|
723 |
|
724 // MT-LR complete. |
|
725 if (EStartMTLRLocReq == iState) |
|
726 { |
|
727 iState = EWaiting; |
|
728 } |
|
729 |
|
730 // Verify the real position given to the network, this will be the same position |
|
731 // returned as the result of the MO-LR, thus use the entry given by |
|
732 // the test module. |
|
733 |
|
734 T_LbsUtils utils; |
|
735 RPointerArray<TAny>& verifyPosInfoArr = iParent.iSharedData->iVerifyPosInfoArr; |
|
736 |
|
737 TPositionInfo* verifyRealPosInfo = reinterpret_cast<TPositionInfo*>(verifyPosInfoArr[0]); |
|
738 if (!utils.Compare_PosInfo(*verifyRealPosInfo, aPosition)) |
|
739 { |
|
740 INFO_PRINTF1(_L("Failed test, position incorrect.")); |
|
741 SetTestStepResult(EFail); |
|
742 } |
|
743 } |
|
744 |
|
745 void CT_LbsAssDataStep_Main::NotifyMeasurementReportRequestMoreAssistanceData(const TLbsAssistanceDataGroup& aFilter) |
|
746 { |
|
747 // Call base implementation. |
|
748 CT_LbsNetSimStep::NotifyMeasurementReportRequestMoreAssistanceData(aFilter); |
|
749 |
|
750 switch (iTestCaseId) |
|
751 { |
|
752 // Test case LBS-Ass-Data-0042 - Request multiple items of GPS assistance data when not all of |
|
753 // the items are available. |
|
754 case 42: |
|
755 { |
|
756 if (aFilter != EAssistanceDataReferenceLocation) |
|
757 { |
|
758 INFO_PRINTF2(_L("Failed test, incorrect assistance data group filter expecting Ref Location, got %d."), aFilter); |
|
759 SetTestStepResult(EFail); |
|
760 } |
|
761 } |
|
762 break; |
|
763 |
|
764 default: |
|
765 { |
|
766 INFO_PRINTF2(_L("Failed test, got un-expected request for more assistance data with filter value = %d."), aFilter); |
|
767 SetTestStepResult(EFail); |
|
768 } |
|
769 } |
|
770 } |
|
771 |
|
772 void CT_LbsAssDataStep_Main::NotifyMeasurementReportControlFailure(TInt aReason) |
|
773 { |
|
774 // Call base implementation. |
|
775 CT_LbsNetSimStep::NotifyMeasurementReportControlFailure(aReason); |
|
776 |
|
777 switch (iTestCaseId) |
|
778 { |
|
779 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
780 case 12: |
|
781 { |
|
782 if (aReason != KErrCancel) |
|
783 { |
|
784 INFO_PRINTF2(_L("Failed test, incorrect reason code expecting KErrCancel, got %d."), aReason); |
|
785 SetTestStepResult(EFail); |
|
786 } |
|
787 } |
|
788 break; |
|
789 |
|
790 default: |
|
791 { |
|
792 INFO_PRINTF2(_L("Failed test, got un-expected control failure with reason code = %d."), aReason); |
|
793 SetTestStepResult(EFail); |
|
794 } |
|
795 } |
|
796 } |
|
797 |
|
798 /** Notify position update callback. |
|
799 |
|
800 The notify position update as completed. We can mark as done in the callback flags. |
|
801 */ |
|
802 void CT_LbsAssDataStep_Main::MT_LbsDoPosUpdateCallback(TRequestStatus& aStatus) |
|
803 { |
|
804 INFO_PRINTF1(_L("Got - Notify Update - Callback Event.")); |
|
805 |
|
806 // We should wait for the agps update (first one will be reference position) before setting this flag |
|
807 if(iState != EFirstPosUpdate) |
|
808 { |
|
809 SetCallbackFlag(KLbsCallback_Got_NotifyUpdate); |
|
810 } |
|
811 |
|
812 if (KErrNone != aStatus.Int()) |
|
813 { |
|
814 INFO_PRINTF2(_L("Failed test, pos info request err = %d."), aStatus.Int()); |
|
815 SetTestStepResult(EFail); |
|
816 } |
|
817 |
|
818 // iState is in EFirstPosUpdate after quick off first iDoPosUpdate |
|
819 if (iState == EFirstPosUpdate) |
|
820 { |
|
821 /* iCurrentPosInfoArr index 0 contains ref pos,we need to store this in |
|
822 iCurrentPosInfoArr index 1 for later use,before index 0 updated with realpos*/ |
|
823 RPointerArray<TAny>& posInfoArr = iParent.iSharedData->iCurrentPosInfoArr; |
|
824 TPositionInfo* posInfo = reinterpret_cast<TPositionInfo*>(posInfoArr[0]); |
|
825 |
|
826 //Some tests don't need to store ref pos |
|
827 switch (iTestCaseId) |
|
828 { |
|
829 // Test case LBS-Ass-Data-0012 - Cancel assistance data request test. |
|
830 case 12: |
|
831 // Test case LBS-Ass-Data-0040 - Empty GPS assistance data cache test. |
|
832 case 40: |
|
833 // Test case LBS-Ass-Data-0041 - Request GPS assistance data when no network available. |
|
834 case 41: |
|
835 { |
|
836 // Do nothing. |
|
837 } |
|
838 break; |
|
839 |
|
840 default: |
|
841 { |
|
842 TPositionInfo* refPosInfo = new(ELeave) TPositionInfo(); |
|
843 |
|
844 // Copy ref loc from posInfo to refPosInfo |
|
845 TInt err = CopyPositionTypes(*refPosInfo, *posInfo); |
|
846 if (err) |
|
847 { |
|
848 delete refPosInfo; |
|
849 INFO_PRINTF2(_L("Failed test, err %d copying position infos."), err); |
|
850 SetTestStepResult(EFail); |
|
851 } |
|
852 // Append ref loc to iCurrentPosInfoArr[1] for later use |
|
853 posInfoArr.Append(refPosInfo); |
|
854 |
|
855 } |
|
856 } |
|
857 |
|
858 // Kick off pos update - this will invoke the real position |
|
859 iDoPosUpdate->StartL(*posInfo); |
|
860 |
|
861 // Move to the waiting state after kick off second pos update |
|
862 iState = CT_LbsNetSimStep::EWaiting; |
|
863 } |
|
864 } |
|
865 |
|
866 |
|
867 /** The module's output data bus has been updated. |
|
868 This function is called when the module sends back answers to both the assistance data checks |
|
869 and module test mode updates. */ |
|
870 void CT_LbsAssDataStep_Main::HandleDataBusUpdateL(const TModuleDataOut& aModuleDataOut) |
|
871 { |
|
872 INFO_PRINTF1(_L("Got - Module Response - Callback Event.")); |
|
873 |
|
874 SetCallbackFlag(KLbsCallback_Got_ModuleAssDataAnswer); |
|
875 |
|
876 switch (iTestCaseId) |
|
877 { |
|
878 // |
|
879 case 1: |
|
880 { |
|
881 // TODO: Look for startup - shutdown ok responses... |
|
882 } |
|
883 break; |
|
884 |
|
885 // Check for cancel request response. |
|
886 case 12: |
|
887 { |
|
888 if(aModuleDataOut.iRequestType == TModuleDataOut::EModuleResponse) |
|
889 { |
|
890 //modDataOut.iResponse = TModuleDataOut::EModuleAssDataOk; |
|
891 switch (aModuleDataOut.iResponse) |
|
892 { |
|
893 case TModuleDataOut::EModuleResponseOk: |
|
894 INFO_PRINTF1(_L(" Cancel request, module response.")); |
|
895 break; |
|
896 |
|
897 default: |
|
898 INFO_PRINTF1(_L("Failed test, unexpected response from module.")); |
|
899 SetTestStepResult(EFail); |
|
900 break; |
|
901 } |
|
902 |
|
903 } |
|
904 |
|
905 else |
|
906 { |
|
907 INFO_PRINTF1(_L("Failed test, unexpected request type from module.")); |
|
908 SetTestStepResult(EFail); |
|
909 } |
|
910 } |
|
911 break; |
|
912 |
|
913 default: |
|
914 { |
|
915 INFO_PRINTF1(_L(" Assistance Data Verify Answer.")); |
|
916 |
|
917 switch (aModuleDataOut.iResponse) |
|
918 { |
|
919 // Fail test if ass data failed verifcation, or received un-expected response code. |
|
920 case TModuleDataOut::EModuleAssDataOk: |
|
921 { |
|
922 // Ensure we only get a single assistance data event for each test, except for LBS-Ass-Data_0042 |
|
923 if (iTestCaseId != 42) |
|
924 { |
|
925 iAssEventCount++; |
|
926 } |
|
927 |
|
928 if (iAssEventCount > 2) |
|
929 { |
|
930 INFO_PRINTF1(_L("Failed test, more than a single assistance data event receivced.")); |
|
931 SetTestStepResult(EFail); |
|
932 } |
|
933 } |
|
934 break; |
|
935 |
|
936 // Ignore requests for assistance data. |
|
937 case TModuleDataOut::EModuleAssDataRequestedOk: |
|
938 // Do nothing. |
|
939 break; |
|
940 |
|
941 default: |
|
942 { |
|
943 INFO_PRINTF2(_L("Failed test, module assistance data verification, got: %d."), aModuleDataOut.iResponse); |
|
944 SetTestStepResult(EFail); |
|
945 } |
|
946 break; |
|
947 } |
|
948 } |
|
949 break; |
|
950 } |
|
951 } |
|
952 |
|
953 |
|
954 /** Privacy controller callbacks. |
|
955 */ |
|
956 void CT_LbsAssDataStep_Main::ProcessNetworkLocationRequest(TUint aRequestId, const TLbsExternalRequestInfo& aRequestInfo, const TNotificationType& aNotificationType) |
|
957 { |
|
958 // We not aiming to test MT-LR here so only carryout minimal verification - verify the request id only. |
|
959 (void)aRequestInfo; |
|
960 (void)aNotificationType; |
|
961 |
|
962 iPrivacyController->RespondNetworkLocationRequest(aRequestId, CLbsPrivacyController::ERequestAccepted); |
|
963 |
|
964 iMtlrRequestId = aRequestId; |
|
965 } |
|
966 |
|
967 |
|
968 void CT_LbsAssDataStep_Main::ProcessNetworkPositionUpdate(TUint aRequestId, const TPositionInfo& aPosInfo) |
|
969 { |
|
970 // Verify the request id. |
|
971 if (aRequestId != iMtlrRequestId) |
|
972 { |
|
973 INFO_PRINTF3(_L("Failed test, incorrect request ID, got %d, expecting %d."), aRequestId, iMtlrRequestId); |
|
974 SetTestStepResult(EFail); |
|
975 } |
|
976 |
|
977 // Create a posinfo and store in our shared array for later verification. |
|
978 RPointerArray<TAny>& posInfoArr = iParent.iSharedData->iCurrentPosInfoArr; |
|
979 TPositionInfo* posInfo = new(ELeave) TPositionInfo(); |
|
980 |
|
981 T_LbsUtils utils; |
|
982 utils.ResetAndDestroy_PosInfoArr(posInfoArr); // Clear previous entries before new entry is appended. |
|
983 |
|
984 // As we don't own the passed posinfo, copy it. |
|
985 TInt err = CopyPositionTypes(*posInfo, aPosInfo); |
|
986 if (err) |
|
987 { |
|
988 INFO_PRINTF2(_L("Failed test, err %d copying position infos."), err); |
|
989 SetTestStepResult(EFail); |
|
990 } |
|
991 |
|
992 posInfoArr.Append(posInfo); |
|
993 } |
|
994 |
|
995 |
|
996 void CT_LbsAssDataStep_Main::ProcessRequestComplete(TUint aRequestId, TInt aReason) |
|
997 { |
|
998 // Verify the request id. |
|
999 if (aRequestId != iMtlrRequestId) |
|
1000 { |
|
1001 INFO_PRINTF3(_L("Failed test, incorrect request ID, got %d, expecting %d."), aRequestId, iMtlrRequestId); |
|
1002 SetTestStepResult(EFail); |
|
1003 } |
|
1004 |
|
1005 // Verify the reason code. |
|
1006 if (aReason) |
|
1007 { |
|
1008 INFO_PRINTF2(_L("Failed test, incorrect reason code, got %d, expecting KErrNone."), aReason); |
|
1009 SetTestStepResult(EFail); |
|
1010 } |
|
1011 } |
|
1012 |
|
1013 /** Helper functions taken from internal Lbs utilities. |
|
1014 */ |
|
1015 |
|
1016 /** |
|
1017 Deep copy of position info data by type |
|
1018 |
|
1019 @param aTo the destination position info object reference |
|
1020 @param aFrom the source position info object reference |
|
1021 @internalComponent |
|
1022 @released |
|
1023 */ |
|
1024 TInt CopyPositionTypes(TPositionInfoBase& aTo, const TPositionInfoBase& aFrom) |
|
1025 { |
|
1026 const TUint32 toClassType = aTo.PositionClassType(); |
|
1027 const TUint toClassSize = aTo.PositionClassSize(); |
|
1028 const TUint32 fromClassType = aFrom.PositionClassType(); |
|
1029 const TUint fromClassSize = aFrom.PositionClassSize(); |
|
1030 |
|
1031 // check for self assignment |
|
1032 if(&aTo == &aFrom) |
|
1033 { |
|
1034 return KErrNone; // copy is implicit and already done :) |
|
1035 } |
|
1036 // check the assignment is even possible the source type must be at |
|
1037 // at least as BIG as the dest, or you leave unitialized data in the destination |
|
1038 if(fromClassSize < toClassSize) |
|
1039 return KErrArgument; |
|
1040 // check we are not assigning base types |
|
1041 if(toClassSize == sizeof(TPositionInfoBase) |
|
1042 || fromClassSize == sizeof(TPositionInfoBase) |
|
1043 || toClassType == EPositionInfoUnknownClass // this the type of a TPositionInfoBase |
|
1044 || fromClassType == EPositionInfoUnknownClass) |
|
1045 { |
|
1046 return KErrArgument; // bad types - trying to copy between base types |
|
1047 } |
|
1048 // check the aTo type |
|
1049 TInt typeError = SupportedType(toClassType, toClassSize); |
|
1050 if(typeError != KErrNone) |
|
1051 return typeError; // i.e. KErrNotSupported |
|
1052 // check the aFromType |
|
1053 typeError = SupportedType(fromClassType, fromClassSize); |
|
1054 if(typeError != KErrNone) |
|
1055 return typeError; // i.e. KErrNotSupported |
|
1056 // Ok now we know we can copy these things from one to the other |
|
1057 // so here goes - the catch is we cannot overwrite the type and size |
|
1058 // of the destination, so we need a bit of pointer math. |
|
1059 // NB this relies on the being a class inheritance such that all of the |
|
1060 // types are derived from TPositionInfoBase first. Or the math goes |
|
1061 // haywire. This also implies a whole slew of assumptions about the ram |
|
1062 // layout of these classes.... |
|
1063 TUint8* baseToAddr = reinterpret_cast<TUint8*>(&aTo)+sizeof(TPositionInfoBase); |
|
1064 const TUint8* const baseFromAddr = reinterpret_cast<const TUint8*>(&aFrom)+sizeof(TPositionInfoBase); |
|
1065 TUint32 dataLength = toClassSize-sizeof(TPositionInfoBase); // we copy only this many bytes form the source |
|
1066 TUint8* endAddr = Mem::Copy(baseToAddr, baseFromAddr, dataLength); |
|
1067 // Sanity check the Mem::Copy() - just in case... |
|
1068 if(endAddr != baseToAddr+dataLength) |
|
1069 return KErrGeneral; // Or KErrNoMemory? |
|
1070 else |
|
1071 return KErrNone; |
|
1072 } |
|
1073 |
|
1074 /** |
|
1075 Check the size for supported position info type |
|
1076 |
|
1077 @param aType the position info type |
|
1078 @param aSize the size of specified type |
|
1079 @return Symbian standard error code |
|
1080 @internalComponent |
|
1081 @released |
|
1082 */ |
|
1083 TInt SupportedType(const TUint32& aType, const TInt& aSize) |
|
1084 { |
|
1085 if(aType==EPositionInfoClass) |
|
1086 { |
|
1087 if(aSize!=sizeof(TPositionInfo)) |
|
1088 return KErrNotSupported; // something weird. Type ok but the size is wrong |
|
1089 } |
|
1090 else if(aType==(EPositionInfoClass|EPositionCourseInfoClass)) |
|
1091 { |
|
1092 if(aSize!=sizeof(TPositionCourseInfo)) |
|
1093 return KErrNotSupported; // something weird. Type ok but the size is wrong |
|
1094 } |
|
1095 else if(aType==(EPositionInfoClass|EPositionCourseInfoClass|EPositionSatelliteInfoClass)) |
|
1096 { |
|
1097 if(aSize!=sizeof(TPositionSatelliteInfo)) |
|
1098 return KErrNotSupported; // something weird. Type ok but the size is wrong |
|
1099 } |
|
1100 // othwerwise the size and type are what we expected |
|
1101 return KErrNone; |
|
1102 } |
|
1103 |