Convert Kernelhwsrv package from SFL to EPL
kernel\eka\compsupp is subject to the ARM EABI LICENSE
userlibandfileserver\fatfilenameconversionplugins\unicodeTables is subject to the Unicode license
kernel\eka\kernel\zlib is subject to the zlib license
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// testcaseb2broot.cpp
// @internalComponent
//
//
#include <e32std.h>
#include <e32std_private.h>
#include <u32std.h> // unicode builds
#include <e32base.h>
#include <e32base_private.h>
#include <e32cons.h>
#include <e32Test.h> // RTest header
#include <e32ver.h>
#include <e32def.h>
#include <e32def_private.h>
#include <d32otgdi.h> // OTGDI header
#include <d32usbc.h> // USBCC header
#include "testcaseroot.h"
#include "b2bwatchers.h"
void CNotifyWatcherBase::RunL()
{
DisplayEvent();
iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards
IssueAgain();
SetActive();
}
CNotifyCollector::CNotifyCollector(TRequestStatus &aStatus) : iStatusStep(aStatus)
{
LOG_FUNC
TTimeIntervalDays oneday(1);
iTimeStarted.HomeTime();
iTimeStarted += (oneday); // force all durations to produce a negative (invalid) value
}
/***************************************************************
* ~CNotifyCollector
*/
CNotifyCollector::~CNotifyCollector()
{
LOG_FUNC
ClearAllEvents(); // free event arrays
iNotifyObjects.Close();
iFailureEvents.Close();
iRequiredEvents.Close();
iReceivedEvents.Close();
}
/* The test-case calls this to clear the events stored.
* Both the expected and already recieved events get cleared, this method
* is typically called at the start of each test-step
*/
void CNotifyCollector::ClearAllEvents(TBool aClearRecieved/*=ETrue*/, TBool aClearRequired /*=ETrue*/)
{
//LOG_FUNC
if (aClearRequired)
{
iRequiredEvents.Reset();
iFailureEvents.Reset();
}
if (aClearRecieved)
{
iReceivedEvents.Reset();
}
}
/* Creates and starts all 4 observers
* Note: The Watchdog does not get started, because it needs an interval
*/
void CNotifyCollector::CreateObserversL(COtgRoot &aOtgDriver)
{
LOG_FUNC
TInt watchType;
ASSERT(aOtgDriver.LddLoaded());
for (watchType=EWatcherTimeouts; watchType < EWatcherInvalid; watchType++)
{
CNotifyWatcherBase *pWatcher=0;
switch ((TWatcherNotifyType )watchType)
{
case EWatcherTimeouts:
pWatcher = COtgWatchdogWatcher::NewL(*this, EWatcherTimeouts, aOtgDriver);
break;
case EWatcherState:
pWatcher = COtgStateWatcher::NewL(*this , EWatcherState, aOtgDriver);
break;
case EWatcherEvent:
pWatcher = COtgEventWatcher::NewL(*this, EWatcherEvent, aOtgDriver);
break;
case EWatcherMessage:
pWatcher = COtgMessageWatcher::NewL(*this, EWatcherMessage, aOtgDriver);
break;
case EWatcherPeripheralState:
pWatcher = CPeripheralStateWatcher::NewL(*this, EWatcherPeripheralState, aOtgDriver);
break;
case EWatcherAConnectionIdle:
pWatcher = CAConnectionIdleWatcher::NewL(*this, EWatcherAConnectionIdle, aOtgDriver);
break;
}
// the TRequest object is added to scheduler in it's own constructor
// add it to our list so we can kill them after the test.
iNotifyObjects.Append(pWatcher);
//LOG_VERBOSE3(_L("Added watcher type %d, TRequest= %08X.\n"), iType, (TInt)(&pWatcher->iStatus));
// start all watchers, except for the watchdog
if (watchType != EWatcherTimeouts)
{
pWatcher->StartWatching(-1);
}
}
test.Printf(_L("\n"));
}
/* NOTE: OTG must still be loaded or else we cannot cancel the outstanding event watches here!
*/
void CNotifyCollector::DestroyObservers()
{
LOG_FUNC
// Free the Watchers
for (TInt idx=0; idx < iNotifyObjects.Count(); idx++)
{
LOG_VERBOSE2(_L(".. %d .."), idx);
delete iNotifyObjects[idx]; // they will call their own Cancel() methods
}
iNotifyObjects.Close();
}
void CNotifyCollector::AddRequiredNotification(TWatcherNotifyType aType, TInt aValue)
{
AddRequiredOrFailureNotification(aType, aValue, EFalse);
}
void CNotifyCollector:: AddFailureNotification(const TWatcherNotifyType aType, TInt aValue)
{
AddRequiredOrFailureNotification(aType, aValue, ETrue);
}
/* Checks that a watcher for the event exists, and then adds it to a list of events required for a PASS condition
* The timout event does not get added to this list.
* If the parameter is a time, the timer gets started
* If aEventMeansFailure is set True, then the reception of the event will cause the current test step to fail
*/
void CNotifyCollector::AddRequiredOrFailureNotification(TWatcherNotifyType aType, TInt aValue, TBool aEventMeansFailure)
{
CNotifyWatcherBase *pWatcher=0;
TInt index=0;
TBuf<MAX_DSTRLEN> aDescription;
// print a usefull debug message
switch (aType)
{
case EWatcherTimeouts:
break;
case EWatcherState:
COtgRoot::OtgStateString(static_cast<RUsbOtgDriver::TOtgState>(aValue), aDescription);
LOG_VERBOSE3(_L("AddRequiredNotification() State %d '%S' wanted\n"), aValue, &aDescription);
break;
case EWatcherEvent:
COtgRoot::OtgEventString(static_cast<RUsbOtgDriver::TOtgEvent>(aValue), aDescription);
LOG_VERBOSE3(_L("AddRequiredNotification() Event %d '%S' wanted\n"), aValue, &aDescription);
break;
case EWatcherMessage:
COtgRoot::OtgMessageString(static_cast<RUsbOtgDriver::TOtgMessage>(aValue), aDescription);
LOG_VERBOSE3(_L("AddRequiredNotification() Message %d '%S' wanted\n"), aValue, &aDescription);
break;
case EWatcherPeripheralState:
COtgRoot::PeripheralStateString(static_cast<TUint>(aValue), aDescription);
LOG_VERBOSE3(_L("AddRequiredNotification() Peripheral State %d '%S' wanted\n"), aValue, &aDescription);
break;
case EWatcherAConnectionIdle:
COtgRoot::AConnectionIdleString(static_cast<RUsbOtgDriver::TOtgConnection>(aValue), aDescription);
LOG_VERBOSE3(_L("AddRequiredNotification() AConnectionIdle %d '%S' wanted\n"), aValue, &aDescription);
break;
}
// Find the watcher if possible
while (index < iNotifyObjects.Count())
{
TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!"));
if (iNotifyObjects[index]->GetType() == aType)
{
pWatcher = iNotifyObjects[index];
break;
}
index++;
}
TEST_ASSERTION(pWatcher!=NULL, _L("pWatcher=0!"));
if (aType == EWatcherTimeouts)
{ // other watchers are already running, but we start the timer now
pWatcher->StartWatching(aValue);
}
else
{ // timeouts are not added to the Q
TOtgObservedEvent evt(aType, aValue);
if(aEventMeansFailure)
{
iFailureEvents.Append(evt);
}
else
{
iRequiredEvents.Append(evt);
}
}
// flag as pending
iStatusStep = KRequestPending;
iTimeStarted.HomeTime();
}
/* Return the number of milliseconds since the last call to AddRequiredNotification()
*/
TInt CNotifyCollector::DurationElapsed()
{
TTime TimeEnd;
TInt Millisec;
TimeEnd.HomeTime();
TTimeIntervalMicroSeconds ivlMicro(TimeEnd.MicroSecondsFrom(iTimeStarted));
Millisec = (TInt)(ivlMicro.Int64())/1000; // USB times are in uSec, but in ms for the user layer
if (Millisec < 0)
Millisec = -1; // TRUE for when the Notifiers are not yet being used.
return(Millisec);
}
/* Search for an event in the received Q
* @return :TRUE if the specified event has been received
*/
TBool CNotifyCollector::EventReceivedAlready(const TOtgObservedEvent& aEvent)
{
for (TInt idx=0; idx < iReceivedEvents.Count(); idx++)
if (iReceivedEvents[idx] == aEvent)
return(ETrue);
return(EFalse);
}
/* Search for an event in the failure event queue
* @return :TRUE if the specified event does denote a failure
*/
TBool CNotifyCollector::IsFailureEvent(TOtgObservedEvent &aEvent)
{
for (TInt idx=0; idx < iFailureEvents.Count(); idx++)
if (iFailureEvents[idx] == aEvent)
return(ETrue);
return(EFalse);
}
/* @return 0 if the watcher has not yet been created. (for instance early in the test)
*/
CNotifyWatcherBase* CNotifyCollector::GetWatcher(TWatcherNotifyType aType)
{
CNotifyWatcherBase *pWatcher=0;
// Find the watcher
TInt index=0;
while (index < iNotifyObjects.Count())
{
TEST_ASSERTION(iNotifyObjects[index]!=NULL, _L("iNotifyObjects element gone!"));
if (iNotifyObjects[index]->GetType() == aType)
{
pWatcher = iNotifyObjects[index];
break;
}
index++;
}
return(pWatcher);
}
/* Process the event. The OTG watchers are responsible for renewing themselves
* but the Timer event does not renew
*/
void CNotifyCollector::HandleEvent(TWatcherNotifyType aType, TInt aValue)
{
if (aType == EWatcherTimeouts)
{
test.Printf(_L("Step timed out..(%dms).\n\n"), GetWatcher(aType)->GetEventValue());
CompleteStep(KTestCaseWatchdogTO);
return;
}
TOtgObservedEvent evt(aType, aValue);
TInt start=0;
iReceivedEvents.Append(evt); // store incomming evt
// Check to see whether the event denotes a failure for this event
if (IsFailureEvent(evt))
{
test.Printf(_L("This event denotes failure for this test\n"));
CompleteStep(KTestCaseFailureEventReceived);
return;
}
if (iRequiredEvents.Count())
{
// itterate all required events, search for each one in the incomming events list
while (start< iRequiredEvents.Count())
{
//LOG_VERBOSE3(_L("Search for=[%d,%d] :"),
// iRequiredEvents[start].GetType(), iRequiredEvents[start].GetValue());
if (!EventReceivedAlready(iRequiredEvents[start]))
return; // missing still, continue
start++;
}
// found all the required events
LOG_VERBOSE1(_L("Found all.\n"));
CompleteStep(KErrNone);
}
else
{
test.Printf(_L("Warning : No required events!\n"));
}
}
// Complete the test step's TRequestStatus (checking it is currently KRequestPending
// to try and avoid multiple completions).
//
void CNotifyCollector::CompleteStep(TInt aCompletionCode)
{
if(iStatusStep.Int() != KRequestPending)
{
test.Printf(_L("Can't complete step - not KRequestPending!\n"));
}
else
{
TRequestStatus *StatusStepPtr = &iStatusStep;
User::RequestComplete(StatusStepPtr, aCompletionCode);
}
}
/****************************************************************************
* COtg Watchdog Watcher
*/
COtgWatchdogWatcher *COtgWatchdogWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
LOG_FUNC
COtgWatchdogWatcher* self = new (ELeave) COtgWatchdogWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void COtgWatchdogWatcher::ConstructL()
{
LOG_FUNC
iTimer.CreateLocal();
iIntervalMs = -1;
}
void COtgWatchdogWatcher::StepExpired(TInt aInterval)
{
LOG_FUNC ;
iHandler.HandleEvent(EWatcherTimeouts, aInterval) ;
}
void COtgWatchdogWatcher::RunL()
{
//LOG_FUNC
StepExpired(iIntervalMs);
}
void COtgWatchdogWatcher::StartTimer(TInt aIntervalMs)
{
LOG_FUNC ;
iIntervalMs = aIntervalMs; // save value for printing latter
if (IsActive()) //cancel the last timer we set, this is easier than cancelling it in each test-step
{
iTimer.Cancel();
User::WaitForRequest(iStatus); // swallow it
iTimer.After(iStatus, aIntervalMs*1000);
}
else
{
iTimer.After(iStatus, aIntervalMs*1000);
SetActive();
}
LOG_VERBOSE2(_L("wd Timer %dms\n"), aIntervalMs)
}
/****************************************************************************
* OTG Event/State/Message Watchers
*/
COtgMessageWatcher* COtgMessageWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
LOG_FUNC
COtgMessageWatcher* self = new (ELeave) COtgMessageWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void COtgMessageWatcher::DisplayEvent()
{
TBuf<MAX_DSTRLEN> aDescription;
iOtgRoot.OtgMessageString(iMessage, aDescription);
test.Printf(_L("Received Message %d '%S'\n"), iMessage, &aDescription);
}
COtgStateWatcher* COtgStateWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
LOG_FUNC
COtgStateWatcher* self = new (ELeave) COtgStateWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void COtgStateWatcher::DisplayEvent()
{
//LOG_FUNC
TBuf<MAX_DSTRLEN> aDescription;
iOtgRoot.OtgStateString(iState, aDescription);
test.Printf(_L("Received State %d '%S'\n"), iState, &aDescription);
}
COtgEventWatcher* COtgEventWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
//LOG_FUNC
COtgEventWatcher* self = new (ELeave) COtgEventWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void COtgEventWatcher::DisplayEvent()
{
TBuf<MAX_DSTRLEN> aDescription;
iOtgRoot.OtgEventString(iEvent, aDescription);
test.Printf(_L("Received Event %d '%S'\n"), iEvent, &aDescription);
}
CPeripheralStateWatcher* CPeripheralStateWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
//LOG_FUNC
CPeripheralStateWatcher* self = new (ELeave) CPeripheralStateWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CPeripheralStateWatcher::DisplayEvent()
{
TBuf<MAX_DSTRLEN> aDescription;
iOtgRoot.PeripheralStateString(iPeripheralState, aDescription);
test.Printf(_L("Peripheral State %d '%S'\n"), iPeripheralState, &aDescription);
}
CAConnectionIdleWatcher* CAConnectionIdleWatcher::NewL(MOtgNotificationHandler &wdHandler,
const TWatcherNotifyType aWatchType,
COtgRoot &aOtgRoot)
{
//LOG_FUNC
CAConnectionIdleWatcher* self = new (ELeave) CAConnectionIdleWatcher(wdHandler, aWatchType, aOtgRoot);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CAConnectionIdleWatcher::RunL()
{
// We need to override the RunL for this event type, as
// the semantics of the asynchronous function are somewhat
// different to the rest of the ones being serviced by
// CNotifyWatcherBase.
//
// In the case of QueueOtgConnectionNotification, the value
// passed in is updated *immediately* to reflect the current
// activity or otherwise of the connection (unlike the other
// async functions which update the value on completion).
// The completion in the case of QueueOtgConnectionNotification
// is used to indicate that the value has changed, and
// another request should be queued to pick up this new value.
//
// The practical upshot of this is that the IssueAgain needs
// to happen before the event is displayed and handled...
IssueAgain();
DisplayEvent();
iHandler.HandleEvent(iWatchType, GetEventValue()); // report the event upwards
SetActive();
}
void CAConnectionIdleWatcher::DisplayEvent()
{
TBuf<MAX_DSTRLEN> aDescription;
iOtgRoot.AConnectionIdleString(iAConnectionIdle, aDescription);
test.Printf(_L("AConnectionIdle %d '%S'\n"), iAConnectionIdle, &aDescription);
}