|
1 // Copyright (c) 2007-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 the License "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 // testcaseb2broot.cpp |
|
15 // @internalComponent |
|
16 // |
|
17 // |
|
18 |
|
19 #include <e32std.h> |
|
20 #include <e32std_private.h> |
|
21 #include <u32std.h> // unicode builds |
|
22 #include <e32base.h> |
|
23 #include <e32base_private.h> |
|
24 #include <e32cons.h> |
|
25 #include <e32Test.h> // RTest header |
|
26 #include <e32ver.h> |
|
27 #include <e32def.h> |
|
28 #include <e32def_private.h> |
|
29 #include <d32otgdi.h> // OTGDI header |
|
30 #include <d32usbc.h> // USBCC header |
|
31 #include "testcaseroot.h" |
|
32 #include "b2bwatchers.h" |
|
33 |
|
34 |
|
35 |
|
36 void CNotifyWatcherBase::RunL() |
|
37 { |
|
38 DisplayEvent(); |
|
39 iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards |
|
40 |
|
41 IssueAgain(); |
|
42 SetActive(); |
|
43 } |
|
44 |
|
45 |
|
46 CNotifyCollector::CNotifyCollector(TRequestStatus &aStatus) : iStatusStep(aStatus) |
|
47 { |
|
48 LOG_FUNC |
|
49 TTimeIntervalDays oneday(1); |
|
50 iTimeStarted.HomeTime(); |
|
51 iTimeStarted += (oneday); // force all durations to produce a negative (invalid) value |
|
52 } |
|
53 |
|
54 |
|
55 /*************************************************************** |
|
56 * ~CNotifyCollector |
|
57 */ |
|
58 CNotifyCollector::~CNotifyCollector() |
|
59 { |
|
60 LOG_FUNC |
|
61 |
|
62 ClearAllEvents(); // free event arrays |
|
63 |
|
64 iNotifyObjects.Close(); |
|
65 iFailureEvents.Close(); |
|
66 iRequiredEvents.Close(); |
|
67 iReceivedEvents.Close(); |
|
68 } |
|
69 |
|
70 |
|
71 /* The test-case calls this to clear the events stored. |
|
72 * Both the expected and already recieved events get cleared, this method |
|
73 * is typically called at the start of each test-step |
|
74 */ |
|
75 void CNotifyCollector::ClearAllEvents(TBool aClearRecieved/*=ETrue*/, TBool aClearRequired /*=ETrue*/) |
|
76 { |
|
77 //LOG_FUNC |
|
78 if (aClearRequired) |
|
79 { |
|
80 iRequiredEvents.Reset(); |
|
81 iFailureEvents.Reset(); |
|
82 } |
|
83 if (aClearRecieved) |
|
84 { |
|
85 iReceivedEvents.Reset(); |
|
86 } |
|
87 } |
|
88 |
|
89 |
|
90 /* Creates and starts all 4 observers |
|
91 * Note: The Watchdog does not get started, because it needs an interval |
|
92 */ |
|
93 void CNotifyCollector::CreateObserversL(COtgRoot &aOtgDriver) |
|
94 { |
|
95 LOG_FUNC |
|
96 TInt watchType; |
|
97 ASSERT(aOtgDriver.LddLoaded()); |
|
98 |
|
99 for (watchType=EWatcherTimeouts; watchType < EWatcherInvalid; watchType++) |
|
100 { |
|
101 CNotifyWatcherBase *pWatcher=0; |
|
102 switch ((TWatcherNotifyType )watchType) |
|
103 { |
|
104 case EWatcherTimeouts: |
|
105 pWatcher = COtgWatchdogWatcher::NewL(*this, EWatcherTimeouts, aOtgDriver); |
|
106 break; |
|
107 case EWatcherState: |
|
108 pWatcher = COtgStateWatcher::NewL(*this , EWatcherState, aOtgDriver); |
|
109 break; |
|
110 case EWatcherEvent: |
|
111 pWatcher = COtgEventWatcher::NewL(*this, EWatcherEvent, aOtgDriver); |
|
112 break; |
|
113 case EWatcherMessage: |
|
114 pWatcher = COtgMessageWatcher::NewL(*this, EWatcherMessage, aOtgDriver); |
|
115 break; |
|
116 case EWatcherPeripheralState: |
|
117 pWatcher = CPeripheralStateWatcher::NewL(*this, EWatcherPeripheralState, aOtgDriver); |
|
118 break; |
|
119 case EWatcherAConnectionIdle: |
|
120 pWatcher = CAConnectionIdleWatcher::NewL(*this, EWatcherAConnectionIdle, aOtgDriver); |
|
121 break; |
|
122 |
|
123 } |
|
124 // the TRequest object is added to scheduler in it's own constructor |
|
125 |
|
126 // add it to our list so we can kill them after the test. |
|
127 iNotifyObjects.Append(pWatcher); |
|
128 //LOG_VERBOSE3(_L("Added watcher type %d, TRequest= %08X.\n"), iType, (TInt)(&pWatcher->iStatus)); |
|
129 |
|
130 // start all watchers, except for the watchdog |
|
131 if (watchType != EWatcherTimeouts) |
|
132 { |
|
133 pWatcher->StartWatching(-1); |
|
134 } |
|
135 } |
|
136 test.Printf(_L("\n")); |
|
137 } |
|
138 |
|
139 |
|
140 /* NOTE: OTG must still be loaded or else we cannot cancel the outstanding event watches here! |
|
141 */ |
|
142 void CNotifyCollector::DestroyObservers() |
|
143 { |
|
144 LOG_FUNC |
|
145 |
|
146 // Free the Watchers |
|
147 for (TInt idx=0; idx < iNotifyObjects.Count(); idx++) |
|
148 { |
|
149 LOG_VERBOSE2(_L(".. %d .."), idx); |
|
150 delete iNotifyObjects[idx]; // they will call their own Cancel() methods |
|
151 } |
|
152 iNotifyObjects.Close(); |
|
153 } |
|
154 |
|
155 |
|
156 void CNotifyCollector::AddRequiredNotification(TWatcherNotifyType aType, TInt aValue) |
|
157 { |
|
158 AddRequiredOrFailureNotification(aType, aValue, EFalse); |
|
159 } |
|
160 |
|
161 void CNotifyCollector:: AddFailureNotification(const TWatcherNotifyType aType, TInt aValue) |
|
162 { |
|
163 AddRequiredOrFailureNotification(aType, aValue, ETrue); |
|
164 } |
|
165 |
|
166 /* Checks that a watcher for the event exists, and then adds it to a list of events required for a PASS condition |
|
167 * The timout event does not get added to this list. |
|
168 * If the parameter is a time, the timer gets started |
|
169 * If aEventMeansFailure is set True, then the reception of the event will cause the current test step to fail |
|
170 */ |
|
171 void CNotifyCollector::AddRequiredOrFailureNotification(TWatcherNotifyType aType, TInt aValue, TBool aEventMeansFailure) |
|
172 { |
|
173 CNotifyWatcherBase *pWatcher=0; |
|
174 TInt index=0; |
|
175 TBuf<MAX_DSTRLEN> aDescription; |
|
176 |
|
177 // print a usefull debug message |
|
178 switch (aType) |
|
179 { |
|
180 case EWatcherTimeouts: |
|
181 break; |
|
182 case EWatcherState: |
|
183 COtgRoot::OtgStateString(static_cast<RUsbOtgDriver::TOtgState>(aValue), aDescription); |
|
184 LOG_VERBOSE3(_L("AddRequiredNotification() State %d '%S' wanted\n"), aValue, &aDescription); |
|
185 break; |
|
186 case EWatcherEvent: |
|
187 COtgRoot::OtgEventString(static_cast<RUsbOtgDriver::TOtgEvent>(aValue), aDescription); |
|
188 LOG_VERBOSE3(_L("AddRequiredNotification() Event %d '%S' wanted\n"), aValue, &aDescription); |
|
189 break; |
|
190 case EWatcherMessage: |
|
191 COtgRoot::OtgMessageString(static_cast<RUsbOtgDriver::TOtgMessage>(aValue), aDescription); |
|
192 LOG_VERBOSE3(_L("AddRequiredNotification() Message %d '%S' wanted\n"), aValue, &aDescription); |
|
193 break; |
|
194 case EWatcherPeripheralState: |
|
195 COtgRoot::PeripheralStateString(static_cast<TUint>(aValue), aDescription); |
|
196 LOG_VERBOSE3(_L("AddRequiredNotification() Peripheral State %d '%S' wanted\n"), aValue, &aDescription); |
|
197 break; |
|
198 case EWatcherAConnectionIdle: |
|
199 COtgRoot::AConnectionIdleString(static_cast<RUsbOtgDriver::TOtgConnection>(aValue), aDescription); |
|
200 LOG_VERBOSE3(_L("AddRequiredNotification() AConnectionIdle %d '%S' wanted\n"), aValue, &aDescription); |
|
201 break; |
|
202 |
|
203 } |
|
204 |
|
205 // Find the watcher if possible |
|
206 while (index < iNotifyObjects.Count()) |
|
207 { |
|
208 |
|
209 TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!")); |
|
210 |
|
211 if (iNotifyObjects[index]->GetType() == aType) |
|
212 { |
|
213 pWatcher = iNotifyObjects[index]; |
|
214 break; |
|
215 } |
|
216 index++; |
|
217 } |
|
218 |
|
219 TEST_ASSERTION(pWatcher!=NULL, _L("pWatcher=0!")); |
|
220 if (aType == EWatcherTimeouts) |
|
221 { // other watchers are already running, but we start the timer now |
|
222 pWatcher->StartWatching(aValue); |
|
223 } |
|
224 else |
|
225 { // timeouts are not added to the Q |
|
226 TOtgObservedEvent evt(aType, aValue); |
|
227 if(aEventMeansFailure) |
|
228 { |
|
229 iFailureEvents.Append(evt); |
|
230 } |
|
231 else |
|
232 { |
|
233 iRequiredEvents.Append(evt); |
|
234 } |
|
235 } |
|
236 // flag as pending |
|
237 iStatusStep = KRequestPending; |
|
238 iTimeStarted.HomeTime(); |
|
239 } |
|
240 |
|
241 |
|
242 /* Return the number of milliseconds since the last call to AddRequiredNotification() |
|
243 */ |
|
244 TInt CNotifyCollector::DurationElapsed() |
|
245 { |
|
246 TTime TimeEnd; |
|
247 TInt Millisec; |
|
248 |
|
249 TimeEnd.HomeTime(); |
|
250 TTimeIntervalMicroSeconds ivlMicro(TimeEnd.MicroSecondsFrom(iTimeStarted)); |
|
251 Millisec = (TInt)(ivlMicro.Int64())/1000; // USB times are in uSec, but in ms for the user layer |
|
252 |
|
253 if (Millisec < 0) |
|
254 Millisec = -1; // TRUE for when the Notifiers are not yet being used. |
|
255 return(Millisec); |
|
256 } |
|
257 |
|
258 |
|
259 /* Search for an event in the received Q |
|
260 * @return :TRUE if the specified event has been received |
|
261 */ |
|
262 TBool CNotifyCollector::EventReceivedAlready(const TOtgObservedEvent& aEvent) |
|
263 { |
|
264 for (TInt idx=0; idx < iReceivedEvents.Count(); idx++) |
|
265 if (iReceivedEvents[idx] == aEvent) |
|
266 return(ETrue); |
|
267 return(EFalse); |
|
268 } |
|
269 |
|
270 /* Search for an event in the failure event queue |
|
271 * @return :TRUE if the specified event does denote a failure |
|
272 */ |
|
273 TBool CNotifyCollector::IsFailureEvent(TOtgObservedEvent &aEvent) |
|
274 { |
|
275 for (TInt idx=0; idx < iFailureEvents.Count(); idx++) |
|
276 if (iFailureEvents[idx] == aEvent) |
|
277 return(ETrue); |
|
278 return(EFalse); |
|
279 } |
|
280 |
|
281 /* @return 0 if the watcher has not yet been created. (for instance early in the test) |
|
282 */ |
|
283 CNotifyWatcherBase* CNotifyCollector::GetWatcher(TWatcherNotifyType aType) |
|
284 { |
|
285 CNotifyWatcherBase *pWatcher=0; |
|
286 // Find the watcher |
|
287 TInt index=0; |
|
288 |
|
289 while (index < iNotifyObjects.Count()) |
|
290 { |
|
291 |
|
292 TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!")); |
|
293 |
|
294 if (iNotifyObjects[index]->GetType() == aType) |
|
295 { |
|
296 pWatcher = iNotifyObjects[index]; |
|
297 break; |
|
298 } |
|
299 index++; |
|
300 } |
|
301 |
|
302 return(pWatcher); |
|
303 } |
|
304 |
|
305 |
|
306 /* Process the event. The OTG watchers are responsible for renewing themselves |
|
307 * but the Timer event does not renew |
|
308 */ |
|
309 void CNotifyCollector::HandleEvent(TWatcherNotifyType aType, TInt aValue) |
|
310 { |
|
311 if (aType == EWatcherTimeouts) |
|
312 { |
|
313 test.Printf(_L("Step timed out..(%dms).\n\n"), GetWatcher(aType)->GetEventValue()); |
|
314 CompleteStep(KTestCaseWatchdogTO); |
|
315 return; |
|
316 } |
|
317 |
|
318 TOtgObservedEvent evt(aType, aValue); |
|
319 TInt start=0; |
|
320 iReceivedEvents.Append(evt); // store incomming evt |
|
321 |
|
322 // Check to see whether the event denotes a failure for this event |
|
323 if (IsFailureEvent(evt)) |
|
324 { |
|
325 test.Printf(_L("This event denotes failure for this test\n")); |
|
326 CompleteStep(KTestCaseFailureEventReceived); |
|
327 return; |
|
328 } |
|
329 |
|
330 if (iRequiredEvents.Count()) |
|
331 { |
|
332 // itterate all required events, search for each one in the incomming events list |
|
333 while (start< iRequiredEvents.Count()) |
|
334 { |
|
335 //LOG_VERBOSE3(_L("Search for=[%d,%d] :"), |
|
336 // iRequiredEvents[start].GetType(), iRequiredEvents[start].GetValue()); |
|
337 |
|
338 if (!EventReceivedAlready(iRequiredEvents[start])) |
|
339 return; // missing still, continue |
|
340 start++; |
|
341 } |
|
342 // found all the required events |
|
343 LOG_VERBOSE1(_L("Found all.\n")); |
|
344 CompleteStep(KErrNone); |
|
345 } |
|
346 else |
|
347 { |
|
348 test.Printf(_L("Warning : No required events!\n")); |
|
349 } |
|
350 } |
|
351 |
|
352 // Complete the test step's TRequestStatus (checking it is currently KRequestPending |
|
353 // to try and avoid multiple completions). |
|
354 // |
|
355 void CNotifyCollector::CompleteStep(TInt aCompletionCode) |
|
356 { |
|
357 if(iStatusStep.Int() != KRequestPending) |
|
358 { |
|
359 test.Printf(_L("Can't complete step - not KRequestPending!\n")); |
|
360 } |
|
361 else |
|
362 { |
|
363 TRequestStatus *StatusStepPtr = &iStatusStep; |
|
364 User::RequestComplete(StatusStepPtr, aCompletionCode); |
|
365 } |
|
366 } |
|
367 |
|
368 /**************************************************************************** |
|
369 * COtg Watchdog Watcher |
|
370 */ |
|
371 COtgWatchdogWatcher *COtgWatchdogWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
372 const TWatcherNotifyType aWatchType, |
|
373 COtgRoot &aOtgRoot) |
|
374 { |
|
375 LOG_FUNC |
|
376 COtgWatchdogWatcher* self = new (ELeave) COtgWatchdogWatcher(wdHandler, aWatchType, aOtgRoot); |
|
377 CleanupStack::PushL(self); |
|
378 self->ConstructL(); |
|
379 CleanupStack::Pop(self); |
|
380 return self; |
|
381 } |
|
382 |
|
383 |
|
384 void COtgWatchdogWatcher::ConstructL() |
|
385 { |
|
386 LOG_FUNC |
|
387 |
|
388 iTimer.CreateLocal(); |
|
389 iIntervalMs = -1; |
|
390 } |
|
391 |
|
392 |
|
393 void COtgWatchdogWatcher::StepExpired(TInt aInterval) |
|
394 { |
|
395 LOG_FUNC ; |
|
396 iHandler.HandleEvent(EWatcherTimeouts, aInterval) ; |
|
397 } |
|
398 |
|
399 |
|
400 void COtgWatchdogWatcher::RunL() |
|
401 { |
|
402 //LOG_FUNC |
|
403 StepExpired(iIntervalMs); |
|
404 } |
|
405 |
|
406 |
|
407 void COtgWatchdogWatcher::StartTimer(TInt aIntervalMs) |
|
408 { |
|
409 LOG_FUNC ; |
|
410 |
|
411 iIntervalMs = aIntervalMs; // save value for printing latter |
|
412 if (IsActive()) //cancel the last timer we set, this is easier than cancelling it in each test-step |
|
413 { |
|
414 iTimer.Cancel(); |
|
415 User::WaitForRequest(iStatus); // swallow it |
|
416 iTimer.After(iStatus, aIntervalMs*1000); |
|
417 } |
|
418 else |
|
419 { |
|
420 iTimer.After(iStatus, aIntervalMs*1000); |
|
421 SetActive(); |
|
422 } |
|
423 LOG_VERBOSE2(_L("wd Timer %dms\n"), aIntervalMs) |
|
424 } |
|
425 |
|
426 |
|
427 /**************************************************************************** |
|
428 * OTG Event/State/Message Watchers |
|
429 */ |
|
430 COtgMessageWatcher* COtgMessageWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
431 const TWatcherNotifyType aWatchType, |
|
432 COtgRoot &aOtgRoot) |
|
433 { |
|
434 LOG_FUNC |
|
435 COtgMessageWatcher* self = new (ELeave) COtgMessageWatcher(wdHandler, aWatchType, aOtgRoot); |
|
436 CleanupStack::PushL(self); |
|
437 self->ConstructL(); |
|
438 CleanupStack::Pop(self); |
|
439 return self; |
|
440 } |
|
441 |
|
442 |
|
443 void COtgMessageWatcher::DisplayEvent() |
|
444 { |
|
445 TBuf<MAX_DSTRLEN> aDescription; |
|
446 iOtgRoot.OtgMessageString(iMessage, aDescription); |
|
447 test.Printf(_L("Received Message %d '%S'\n"), iMessage, &aDescription); |
|
448 } |
|
449 |
|
450 |
|
451 COtgStateWatcher* COtgStateWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
452 const TWatcherNotifyType aWatchType, |
|
453 COtgRoot &aOtgRoot) |
|
454 { |
|
455 LOG_FUNC |
|
456 COtgStateWatcher* self = new (ELeave) COtgStateWatcher(wdHandler, aWatchType, aOtgRoot); |
|
457 CleanupStack::PushL(self); |
|
458 self->ConstructL(); |
|
459 CleanupStack::Pop(self); |
|
460 return self; |
|
461 } |
|
462 |
|
463 |
|
464 void COtgStateWatcher::DisplayEvent() |
|
465 { |
|
466 //LOG_FUNC |
|
467 TBuf<MAX_DSTRLEN> aDescription; |
|
468 iOtgRoot.OtgStateString(iState, aDescription); |
|
469 test.Printf(_L("Received State %d '%S'\n"), iState, &aDescription); |
|
470 } |
|
471 |
|
472 |
|
473 COtgEventWatcher* COtgEventWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
474 const TWatcherNotifyType aWatchType, |
|
475 COtgRoot &aOtgRoot) |
|
476 { |
|
477 //LOG_FUNC |
|
478 COtgEventWatcher* self = new (ELeave) COtgEventWatcher(wdHandler, aWatchType, aOtgRoot); |
|
479 CleanupStack::PushL(self); |
|
480 self->ConstructL(); |
|
481 CleanupStack::Pop(self); |
|
482 return self; |
|
483 } |
|
484 |
|
485 void COtgEventWatcher::DisplayEvent() |
|
486 { |
|
487 TBuf<MAX_DSTRLEN> aDescription; |
|
488 iOtgRoot.OtgEventString(iEvent, aDescription); |
|
489 test.Printf(_L("Received Event %d '%S'\n"), iEvent, &aDescription); |
|
490 } |
|
491 |
|
492 CPeripheralStateWatcher* CPeripheralStateWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
493 const TWatcherNotifyType aWatchType, |
|
494 COtgRoot &aOtgRoot) |
|
495 { |
|
496 //LOG_FUNC |
|
497 CPeripheralStateWatcher* self = new (ELeave) CPeripheralStateWatcher(wdHandler, aWatchType, aOtgRoot); |
|
498 CleanupStack::PushL(self); |
|
499 self->ConstructL(); |
|
500 CleanupStack::Pop(self); |
|
501 return self; |
|
502 } |
|
503 |
|
504 void CPeripheralStateWatcher::DisplayEvent() |
|
505 { |
|
506 TBuf<MAX_DSTRLEN> aDescription; |
|
507 iOtgRoot.PeripheralStateString(iPeripheralState, aDescription); |
|
508 test.Printf(_L("Peripheral State %d '%S'\n"), iPeripheralState, &aDescription); |
|
509 } |
|
510 |
|
511 CAConnectionIdleWatcher* CAConnectionIdleWatcher::NewL(MOtgNotificationHandler &wdHandler, |
|
512 const TWatcherNotifyType aWatchType, |
|
513 COtgRoot &aOtgRoot) |
|
514 { |
|
515 //LOG_FUNC |
|
516 CAConnectionIdleWatcher* self = new (ELeave) CAConnectionIdleWatcher(wdHandler, aWatchType, aOtgRoot); |
|
517 CleanupStack::PushL(self); |
|
518 self->ConstructL(); |
|
519 CleanupStack::Pop(self); |
|
520 return self; |
|
521 } |
|
522 |
|
523 void CAConnectionIdleWatcher::RunL() |
|
524 { |
|
525 // We need to override the RunL for this event type, as |
|
526 // the semantics of the asynchronous function are somewhat |
|
527 // different to the rest of the ones being serviced by |
|
528 // CNotifyWatcherBase. |
|
529 // |
|
530 // In the case of QueueOtgConnectionNotification, the value |
|
531 // passed in is updated *immediately* to reflect the current |
|
532 // activity or otherwise of the connection (unlike the other |
|
533 // async functions which update the value on completion). |
|
534 // The completion in the case of QueueOtgConnectionNotification |
|
535 // is used to indicate that the value has changed, and |
|
536 // another request should be queued to pick up this new value. |
|
537 // |
|
538 // The practical upshot of this is that the IssueAgain needs |
|
539 // to happen before the event is displayed and handled... |
|
540 |
|
541 IssueAgain(); |
|
542 DisplayEvent(); |
|
543 iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards |
|
544 SetActive(); |
|
545 } |
|
546 |
|
547 |
|
548 void CAConnectionIdleWatcher::DisplayEvent() |
|
549 { |
|
550 TBuf<MAX_DSTRLEN> aDescription; |
|
551 iOtgRoot.AConnectionIdleString(iAConnectionIdle, aDescription); |
|
552 test.Printf(_L("AConnectionIdle %d '%S'\n"), iAConnectionIdle, &aDescription); |
|
553 } |