1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/usbho/t_otgdi/src/b2bwatchers.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,553 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// testcaseb2broot.cpp
1.18 +// @internalComponent
1.19 +//
1.20 +//
1.21 +
1.22 +#include <e32std.h>
1.23 +#include <e32std_private.h>
1.24 +#include <u32std.h> // unicode builds
1.25 +#include <e32base.h>
1.26 +#include <e32base_private.h>
1.27 +#include <e32cons.h>
1.28 +#include <e32Test.h> // RTest header
1.29 +#include <e32ver.h>
1.30 +#include <e32def.h>
1.31 +#include <e32def_private.h>
1.32 +#include <d32otgdi.h> // OTGDI header
1.33 +#include <d32usbc.h> // USBCC header
1.34 +#include "testcaseroot.h"
1.35 +#include "b2bwatchers.h"
1.36 +
1.37 +
1.38 +
1.39 +void CNotifyWatcherBase::RunL()
1.40 + {
1.41 + DisplayEvent();
1.42 + iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards
1.43 +
1.44 + IssueAgain();
1.45 + SetActive();
1.46 + }
1.47 +
1.48 +
1.49 +CNotifyCollector::CNotifyCollector(TRequestStatus &aStatus) : iStatusStep(aStatus)
1.50 + {
1.51 + LOG_FUNC
1.52 + TTimeIntervalDays oneday(1);
1.53 + iTimeStarted.HomeTime();
1.54 + iTimeStarted += (oneday); // force all durations to produce a negative (invalid) value
1.55 + }
1.56 +
1.57 +
1.58 +/***************************************************************
1.59 + * ~CNotifyCollector
1.60 + */
1.61 +CNotifyCollector::~CNotifyCollector()
1.62 + {
1.63 + LOG_FUNC
1.64 +
1.65 + ClearAllEvents(); // free event arrays
1.66 +
1.67 + iNotifyObjects.Close();
1.68 + iFailureEvents.Close();
1.69 + iRequiredEvents.Close();
1.70 + iReceivedEvents.Close();
1.71 + }
1.72 +
1.73 +
1.74 +/* The test-case calls this to clear the events stored.
1.75 + * Both the expected and already recieved events get cleared, this method
1.76 + * is typically called at the start of each test-step
1.77 + */
1.78 +void CNotifyCollector::ClearAllEvents(TBool aClearRecieved/*=ETrue*/, TBool aClearRequired /*=ETrue*/)
1.79 + {
1.80 + //LOG_FUNC
1.81 + if (aClearRequired)
1.82 + {
1.83 + iRequiredEvents.Reset();
1.84 + iFailureEvents.Reset();
1.85 + }
1.86 + if (aClearRecieved)
1.87 + {
1.88 + iReceivedEvents.Reset();
1.89 + }
1.90 + }
1.91 +
1.92 +
1.93 +/* Creates and starts all 4 observers
1.94 + * Note: The Watchdog does not get started, because it needs an interval
1.95 + */
1.96 +void CNotifyCollector::CreateObserversL(COtgRoot &aOtgDriver)
1.97 + {
1.98 + LOG_FUNC
1.99 + TInt watchType;
1.100 + ASSERT(aOtgDriver.LddLoaded());
1.101 +
1.102 + for (watchType=EWatcherTimeouts; watchType < EWatcherInvalid; watchType++)
1.103 + {
1.104 + CNotifyWatcherBase *pWatcher=0;
1.105 + switch ((TWatcherNotifyType )watchType)
1.106 + {
1.107 + case EWatcherTimeouts:
1.108 + pWatcher = COtgWatchdogWatcher::NewL(*this, EWatcherTimeouts, aOtgDriver);
1.109 + break;
1.110 + case EWatcherState:
1.111 + pWatcher = COtgStateWatcher::NewL(*this , EWatcherState, aOtgDriver);
1.112 + break;
1.113 + case EWatcherEvent:
1.114 + pWatcher = COtgEventWatcher::NewL(*this, EWatcherEvent, aOtgDriver);
1.115 + break;
1.116 + case EWatcherMessage:
1.117 + pWatcher = COtgMessageWatcher::NewL(*this, EWatcherMessage, aOtgDriver);
1.118 + break;
1.119 + case EWatcherPeripheralState:
1.120 + pWatcher = CPeripheralStateWatcher::NewL(*this, EWatcherPeripheralState, aOtgDriver);
1.121 + break;
1.122 + case EWatcherAConnectionIdle:
1.123 + pWatcher = CAConnectionIdleWatcher::NewL(*this, EWatcherAConnectionIdle, aOtgDriver);
1.124 + break;
1.125 +
1.126 + }
1.127 + // the TRequest object is added to scheduler in it's own constructor
1.128 +
1.129 + // add it to our list so we can kill them after the test.
1.130 + iNotifyObjects.Append(pWatcher);
1.131 + //LOG_VERBOSE3(_L("Added watcher type %d, TRequest= %08X.\n"), iType, (TInt)(&pWatcher->iStatus));
1.132 +
1.133 + // start all watchers, except for the watchdog
1.134 + if (watchType != EWatcherTimeouts)
1.135 + {
1.136 + pWatcher->StartWatching(-1);
1.137 + }
1.138 + }
1.139 + test.Printf(_L("\n"));
1.140 + }
1.141 +
1.142 +
1.143 +/* NOTE: OTG must still be loaded or else we cannot cancel the outstanding event watches here!
1.144 + */
1.145 +void CNotifyCollector::DestroyObservers()
1.146 + {
1.147 + LOG_FUNC
1.148 +
1.149 + // Free the Watchers
1.150 + for (TInt idx=0; idx < iNotifyObjects.Count(); idx++)
1.151 + {
1.152 + LOG_VERBOSE2(_L(".. %d .."), idx);
1.153 + delete iNotifyObjects[idx]; // they will call their own Cancel() methods
1.154 + }
1.155 + iNotifyObjects.Close();
1.156 + }
1.157 +
1.158 +
1.159 +void CNotifyCollector::AddRequiredNotification(TWatcherNotifyType aType, TInt aValue)
1.160 + {
1.161 + AddRequiredOrFailureNotification(aType, aValue, EFalse);
1.162 + }
1.163 +
1.164 +void CNotifyCollector:: AddFailureNotification(const TWatcherNotifyType aType, TInt aValue)
1.165 + {
1.166 + AddRequiredOrFailureNotification(aType, aValue, ETrue);
1.167 + }
1.168 +
1.169 +/* Checks that a watcher for the event exists, and then adds it to a list of events required for a PASS condition
1.170 + * The timout event does not get added to this list.
1.171 + * If the parameter is a time, the timer gets started
1.172 + * If aEventMeansFailure is set True, then the reception of the event will cause the current test step to fail
1.173 + */
1.174 +void CNotifyCollector::AddRequiredOrFailureNotification(TWatcherNotifyType aType, TInt aValue, TBool aEventMeansFailure)
1.175 + {
1.176 + CNotifyWatcherBase *pWatcher=0;
1.177 + TInt index=0;
1.178 + TBuf<MAX_DSTRLEN> aDescription;
1.179 +
1.180 + // print a usefull debug message
1.181 + switch (aType)
1.182 + {
1.183 + case EWatcherTimeouts:
1.184 + break;
1.185 + case EWatcherState:
1.186 + COtgRoot::OtgStateString(static_cast<RUsbOtgDriver::TOtgState>(aValue), aDescription);
1.187 + LOG_VERBOSE3(_L("AddRequiredNotification() State %d '%S' wanted\n"), aValue, &aDescription);
1.188 + break;
1.189 + case EWatcherEvent:
1.190 + COtgRoot::OtgEventString(static_cast<RUsbOtgDriver::TOtgEvent>(aValue), aDescription);
1.191 + LOG_VERBOSE3(_L("AddRequiredNotification() Event %d '%S' wanted\n"), aValue, &aDescription);
1.192 + break;
1.193 + case EWatcherMessage:
1.194 + COtgRoot::OtgMessageString(static_cast<RUsbOtgDriver::TOtgMessage>(aValue), aDescription);
1.195 + LOG_VERBOSE3(_L("AddRequiredNotification() Message %d '%S' wanted\n"), aValue, &aDescription);
1.196 + break;
1.197 + case EWatcherPeripheralState:
1.198 + COtgRoot::PeripheralStateString(static_cast<TUint>(aValue), aDescription);
1.199 + LOG_VERBOSE3(_L("AddRequiredNotification() Peripheral State %d '%S' wanted\n"), aValue, &aDescription);
1.200 + break;
1.201 + case EWatcherAConnectionIdle:
1.202 + COtgRoot::AConnectionIdleString(static_cast<RUsbOtgDriver::TOtgConnection>(aValue), aDescription);
1.203 + LOG_VERBOSE3(_L("AddRequiredNotification() AConnectionIdle %d '%S' wanted\n"), aValue, &aDescription);
1.204 + break;
1.205 +
1.206 + }
1.207 +
1.208 + // Find the watcher if possible
1.209 + while (index < iNotifyObjects.Count())
1.210 + {
1.211 +
1.212 + TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!"));
1.213 +
1.214 + if (iNotifyObjects[index]->GetType() == aType)
1.215 + {
1.216 + pWatcher = iNotifyObjects[index];
1.217 + break;
1.218 + }
1.219 + index++;
1.220 + }
1.221 +
1.222 + TEST_ASSERTION(pWatcher!=NULL, _L("pWatcher=0!"));
1.223 + if (aType == EWatcherTimeouts)
1.224 + { // other watchers are already running, but we start the timer now
1.225 + pWatcher->StartWatching(aValue);
1.226 + }
1.227 + else
1.228 + { // timeouts are not added to the Q
1.229 + TOtgObservedEvent evt(aType, aValue);
1.230 + if(aEventMeansFailure)
1.231 + {
1.232 + iFailureEvents.Append(evt);
1.233 + }
1.234 + else
1.235 + {
1.236 + iRequiredEvents.Append(evt);
1.237 + }
1.238 + }
1.239 + // flag as pending
1.240 + iStatusStep = KRequestPending;
1.241 + iTimeStarted.HomeTime();
1.242 + }
1.243 +
1.244 +
1.245 +/* Return the number of milliseconds since the last call to AddRequiredNotification()
1.246 + */
1.247 +TInt CNotifyCollector::DurationElapsed()
1.248 + {
1.249 + TTime TimeEnd;
1.250 + TInt Millisec;
1.251 +
1.252 + TimeEnd.HomeTime();
1.253 + TTimeIntervalMicroSeconds ivlMicro(TimeEnd.MicroSecondsFrom(iTimeStarted));
1.254 + Millisec = (TInt)(ivlMicro.Int64())/1000; // USB times are in uSec, but in ms for the user layer
1.255 +
1.256 + if (Millisec < 0)
1.257 + Millisec = -1; // TRUE for when the Notifiers are not yet being used.
1.258 + return(Millisec);
1.259 + }
1.260 +
1.261 +
1.262 +/* Search for an event in the received Q
1.263 + * @return :TRUE if the specified event has been received
1.264 + */
1.265 +TBool CNotifyCollector::EventReceivedAlready(const TOtgObservedEvent& aEvent)
1.266 + {
1.267 + for (TInt idx=0; idx < iReceivedEvents.Count(); idx++)
1.268 + if (iReceivedEvents[idx] == aEvent)
1.269 + return(ETrue);
1.270 + return(EFalse);
1.271 + }
1.272 +
1.273 +/* Search for an event in the failure event queue
1.274 + * @return :TRUE if the specified event does denote a failure
1.275 + */
1.276 +TBool CNotifyCollector::IsFailureEvent(TOtgObservedEvent &aEvent)
1.277 + {
1.278 + for (TInt idx=0; idx < iFailureEvents.Count(); idx++)
1.279 + if (iFailureEvents[idx] == aEvent)
1.280 + return(ETrue);
1.281 + return(EFalse);
1.282 + }
1.283 +
1.284 +/* @return 0 if the watcher has not yet been created. (for instance early in the test)
1.285 + */
1.286 +CNotifyWatcherBase* CNotifyCollector::GetWatcher(TWatcherNotifyType aType)
1.287 + {
1.288 + CNotifyWatcherBase *pWatcher=0;
1.289 + // Find the watcher
1.290 + TInt index=0;
1.291 +
1.292 + while (index < iNotifyObjects.Count())
1.293 + {
1.294 +
1.295 + TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!"));
1.296 +
1.297 + if (iNotifyObjects[index]->GetType() == aType)
1.298 + {
1.299 + pWatcher = iNotifyObjects[index];
1.300 + break;
1.301 + }
1.302 + index++;
1.303 + }
1.304 +
1.305 + return(pWatcher);
1.306 + }
1.307 +
1.308 +
1.309 +/* Process the event. The OTG watchers are responsible for renewing themselves
1.310 + * but the Timer event does not renew
1.311 + */
1.312 +void CNotifyCollector::HandleEvent(TWatcherNotifyType aType, TInt aValue)
1.313 + {
1.314 + if (aType == EWatcherTimeouts)
1.315 + {
1.316 + test.Printf(_L("Step timed out..(%dms).\n\n"), GetWatcher(aType)->GetEventValue());
1.317 + CompleteStep(KTestCaseWatchdogTO);
1.318 + return;
1.319 + }
1.320 +
1.321 + TOtgObservedEvent evt(aType, aValue);
1.322 + TInt start=0;
1.323 + iReceivedEvents.Append(evt); // store incomming evt
1.324 +
1.325 + // Check to see whether the event denotes a failure for this event
1.326 + if (IsFailureEvent(evt))
1.327 + {
1.328 + test.Printf(_L("This event denotes failure for this test\n"));
1.329 + CompleteStep(KTestCaseFailureEventReceived);
1.330 + return;
1.331 + }
1.332 +
1.333 + if (iRequiredEvents.Count())
1.334 + {
1.335 + // itterate all required events, search for each one in the incomming events list
1.336 + while (start< iRequiredEvents.Count())
1.337 + {
1.338 + //LOG_VERBOSE3(_L("Search for=[%d,%d] :"),
1.339 + // iRequiredEvents[start].GetType(), iRequiredEvents[start].GetValue());
1.340 +
1.341 + if (!EventReceivedAlready(iRequiredEvents[start]))
1.342 + return; // missing still, continue
1.343 + start++;
1.344 + }
1.345 + // found all the required events
1.346 + LOG_VERBOSE1(_L("Found all.\n"));
1.347 + CompleteStep(KErrNone);
1.348 + }
1.349 + else
1.350 + {
1.351 + test.Printf(_L("Warning : No required events!\n"));
1.352 + }
1.353 + }
1.354 +
1.355 +// Complete the test step's TRequestStatus (checking it is currently KRequestPending
1.356 +// to try and avoid multiple completions).
1.357 +//
1.358 +void CNotifyCollector::CompleteStep(TInt aCompletionCode)
1.359 + {
1.360 + if(iStatusStep.Int() != KRequestPending)
1.361 + {
1.362 + test.Printf(_L("Can't complete step - not KRequestPending!\n"));
1.363 + }
1.364 + else
1.365 + {
1.366 + TRequestStatus *StatusStepPtr = &iStatusStep;
1.367 + User::RequestComplete(StatusStepPtr, aCompletionCode);
1.368 + }
1.369 + }
1.370 +
1.371 +/****************************************************************************
1.372 + * COtg Watchdog Watcher
1.373 + */
1.374 +COtgWatchdogWatcher *COtgWatchdogWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.375 + const TWatcherNotifyType aWatchType,
1.376 + COtgRoot &aOtgRoot)
1.377 + {
1.378 + LOG_FUNC
1.379 + COtgWatchdogWatcher* self = new (ELeave) COtgWatchdogWatcher(wdHandler, aWatchType, aOtgRoot);
1.380 + CleanupStack::PushL(self);
1.381 + self->ConstructL();
1.382 + CleanupStack::Pop(self);
1.383 + return self;
1.384 + }
1.385 +
1.386 +
1.387 +void COtgWatchdogWatcher::ConstructL()
1.388 + {
1.389 + LOG_FUNC
1.390 +
1.391 + iTimer.CreateLocal();
1.392 + iIntervalMs = -1;
1.393 + }
1.394 +
1.395 +
1.396 +void COtgWatchdogWatcher::StepExpired(TInt aInterval)
1.397 + {
1.398 + LOG_FUNC ;
1.399 + iHandler.HandleEvent(EWatcherTimeouts, aInterval) ;
1.400 + }
1.401 +
1.402 +
1.403 +void COtgWatchdogWatcher::RunL()
1.404 + {
1.405 + //LOG_FUNC
1.406 + StepExpired(iIntervalMs);
1.407 + }
1.408 +
1.409 +
1.410 +void COtgWatchdogWatcher::StartTimer(TInt aIntervalMs)
1.411 + {
1.412 + LOG_FUNC ;
1.413 +
1.414 + iIntervalMs = aIntervalMs; // save value for printing latter
1.415 + if (IsActive()) //cancel the last timer we set, this is easier than cancelling it in each test-step
1.416 + {
1.417 + iTimer.Cancel();
1.418 + User::WaitForRequest(iStatus); // swallow it
1.419 + iTimer.After(iStatus, aIntervalMs*1000);
1.420 + }
1.421 + else
1.422 + {
1.423 + iTimer.After(iStatus, aIntervalMs*1000);
1.424 + SetActive();
1.425 + }
1.426 + LOG_VERBOSE2(_L("wd Timer %dms\n"), aIntervalMs)
1.427 + }
1.428 +
1.429 +
1.430 +/****************************************************************************
1.431 + * OTG Event/State/Message Watchers
1.432 + */
1.433 +COtgMessageWatcher* COtgMessageWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.434 + const TWatcherNotifyType aWatchType,
1.435 + COtgRoot &aOtgRoot)
1.436 + {
1.437 + LOG_FUNC
1.438 + COtgMessageWatcher* self = new (ELeave) COtgMessageWatcher(wdHandler, aWatchType, aOtgRoot);
1.439 + CleanupStack::PushL(self);
1.440 + self->ConstructL();
1.441 + CleanupStack::Pop(self);
1.442 + return self;
1.443 + }
1.444 +
1.445 +
1.446 +void COtgMessageWatcher::DisplayEvent()
1.447 + {
1.448 + TBuf<MAX_DSTRLEN> aDescription;
1.449 + iOtgRoot.OtgMessageString(iMessage, aDescription);
1.450 + test.Printf(_L("Received Message %d '%S'\n"), iMessage, &aDescription);
1.451 + }
1.452 +
1.453 +
1.454 +COtgStateWatcher* COtgStateWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.455 + const TWatcherNotifyType aWatchType,
1.456 + COtgRoot &aOtgRoot)
1.457 + {
1.458 + LOG_FUNC
1.459 + COtgStateWatcher* self = new (ELeave) COtgStateWatcher(wdHandler, aWatchType, aOtgRoot);
1.460 + CleanupStack::PushL(self);
1.461 + self->ConstructL();
1.462 + CleanupStack::Pop(self);
1.463 + return self;
1.464 + }
1.465 +
1.466 +
1.467 +void COtgStateWatcher::DisplayEvent()
1.468 + {
1.469 + //LOG_FUNC
1.470 + TBuf<MAX_DSTRLEN> aDescription;
1.471 + iOtgRoot.OtgStateString(iState, aDescription);
1.472 + test.Printf(_L("Received State %d '%S'\n"), iState, &aDescription);
1.473 + }
1.474 +
1.475 +
1.476 +COtgEventWatcher* COtgEventWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.477 + const TWatcherNotifyType aWatchType,
1.478 + COtgRoot &aOtgRoot)
1.479 + {
1.480 + //LOG_FUNC
1.481 + COtgEventWatcher* self = new (ELeave) COtgEventWatcher(wdHandler, aWatchType, aOtgRoot);
1.482 + CleanupStack::PushL(self);
1.483 + self->ConstructL();
1.484 + CleanupStack::Pop(self);
1.485 + return self;
1.486 + }
1.487 +
1.488 +void COtgEventWatcher::DisplayEvent()
1.489 + {
1.490 + TBuf<MAX_DSTRLEN> aDescription;
1.491 + iOtgRoot.OtgEventString(iEvent, aDescription);
1.492 + test.Printf(_L("Received Event %d '%S'\n"), iEvent, &aDescription);
1.493 + }
1.494 +
1.495 +CPeripheralStateWatcher* CPeripheralStateWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.496 + const TWatcherNotifyType aWatchType,
1.497 + COtgRoot &aOtgRoot)
1.498 + {
1.499 + //LOG_FUNC
1.500 + CPeripheralStateWatcher* self = new (ELeave) CPeripheralStateWatcher(wdHandler, aWatchType, aOtgRoot);
1.501 + CleanupStack::PushL(self);
1.502 + self->ConstructL();
1.503 + CleanupStack::Pop(self);
1.504 + return self;
1.505 + }
1.506 +
1.507 +void CPeripheralStateWatcher::DisplayEvent()
1.508 + {
1.509 + TBuf<MAX_DSTRLEN> aDescription;
1.510 + iOtgRoot.PeripheralStateString(iPeripheralState, aDescription);
1.511 + test.Printf(_L("Peripheral State %d '%S'\n"), iPeripheralState, &aDescription);
1.512 + }
1.513 +
1.514 +CAConnectionIdleWatcher* CAConnectionIdleWatcher::NewL(MOtgNotificationHandler &wdHandler,
1.515 + const TWatcherNotifyType aWatchType,
1.516 + COtgRoot &aOtgRoot)
1.517 + {
1.518 + //LOG_FUNC
1.519 + CAConnectionIdleWatcher* self = new (ELeave) CAConnectionIdleWatcher(wdHandler, aWatchType, aOtgRoot);
1.520 + CleanupStack::PushL(self);
1.521 + self->ConstructL();
1.522 + CleanupStack::Pop(self);
1.523 + return self;
1.524 + }
1.525 +
1.526 +void CAConnectionIdleWatcher::RunL()
1.527 + {
1.528 + // We need to override the RunL for this event type, as
1.529 + // the semantics of the asynchronous function are somewhat
1.530 + // different to the rest of the ones being serviced by
1.531 + // CNotifyWatcherBase.
1.532 + //
1.533 + // In the case of QueueOtgConnectionNotification, the value
1.534 + // passed in is updated *immediately* to reflect the current
1.535 + // activity or otherwise of the connection (unlike the other
1.536 + // async functions which update the value on completion).
1.537 + // The completion in the case of QueueOtgConnectionNotification
1.538 + // is used to indicate that the value has changed, and
1.539 + // another request should be queued to pick up this new value.
1.540 + //
1.541 + // The practical upshot of this is that the IssueAgain needs
1.542 + // to happen before the event is displayed and handled...
1.543 +
1.544 + IssueAgain();
1.545 + DisplayEvent();
1.546 + iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards
1.547 + SetActive();
1.548 + }
1.549 +
1.550 +
1.551 +void CAConnectionIdleWatcher::DisplayEvent()
1.552 + {
1.553 + TBuf<MAX_DSTRLEN> aDescription;
1.554 + iOtgRoot.AConnectionIdleString(iAConnectionIdle, aDescription);
1.555 + test.Printf(_L("AConnectionIdle %d '%S'\n"), iAConnectionIdle, &aDescription);
1.556 + }