diff -r 000000000000 -r 96e5fb8b040d kerneltest/e32test/usbho/t_otgdi/inc/b2bwatchers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/usbho/t_otgdi/inc/b2bwatchers.h Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,396 @@ +#ifndef B2BWATCHERS_H +#define B2BWATCHERS_H +// 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: +// @internalComponent +// +// + + +#include // OTGDI thunk headder (under test) +#include +#include "debugmacros.h" +#include "testcasefactory.h" +#include "testpolicy.h" +#include "testcaseroot.h" + + +// forward: +class CNotifyWatcherBase; + +// types: +enum TWatcherNotifyType + { + EWatcherTimeouts =1, // step watchdog event + EWatcherState, // OTG states + EWatcherEvent, // ... events + EWatcherMessage, // ... messages + EWatcherPeripheralState,// Peripheral device state (undefined, attached, powered etc.) + EWatcherAConnectionIdle,// (A-Device only) whether the connection is idle or busy + EWatcherInvalid + }; + +/* Applicable values in the value member - these are identical to the RUsbOtgDriver enum values, +* but are passed as TInt to be generic +* enum TOtgEvent +* { +* EEventAPlugInserted , +* EEventAPlugRemoved , +* EEventVbusRaised , +* EEventVbusDropped , +* EEventSrpInitiated , +* EEventSrpReceived , +* EEventHnpEnabled , +* EEventHnpDisabled , +* EEventHnpSupported , +* EEventHnpAltSupported , +* EEventRoleChangedToHost , +* EEventRoleChangedToDevice, +* EEventRoleChangedToIdle +* }; +* +* enum TOtgState +* { +* EStateReset , +* EStateAIdle , +* EStateAHost , +* EStateAPeripheral , +* EStateAVbusError , +* EStateBIdle , +* EStateBPeripheral , +* EStateBHost +* }; +* +* enum TOtgMessage +* { +* EEventQueueOverflow , +* EStateQueueOverflow , +* EMessageQueueOverflow , +* EMessageBadState , +* EMessageStackNotStarted , +* EMessageVbusAlreadyRaised , +* EMessageSrpForbidden , +* EMessageBusControlProblem , +* EMessageVbusError , +* EMessageSrpTimeout , +* EMessageSrpActive , +* EMessageSrpNotPermitted , +* EMessageHnpNotPermitted , +* EMessageHnpNotEnabled , +* EMessageHnpNotSuspended , +* EMessageVbusPowerUpNotPermitted , +* EMessageVbusPowerUpError , +* EMessageVbusPowerDownNotPermitted , +* EMessageVbusClearErrorNotPermitted , +* }; + */ + +/* +From d32usbc.h : Device states available from client stack + +enum TUsbcDeviceState + { + EUsbcDeviceStateUndefined, // 0 + EUsbcDeviceStateAttached, // 1 + EUsbcDeviceStatePowered, // 2 + EUsbcDeviceStateDefault, // 3 + EUsbcDeviceStateAddress, // 4 + EUsbcDeviceStateConfigured, // 5 + EUsbcDeviceStateSuspended, // 6 + EUsbcNoState = 0xff // 255 (used as a place holder) + }; + +*/ + +/* Used to save,encapsulate events so we can validate them at the end of a step + */ +class TOtgObservedEvent + { +public: + TOtgObservedEvent() {iValue = EWatcherInvalid;}; + + TOtgObservedEvent(TWatcherNotifyType aType, TInt aValue) : iType(aType), iValue(aValue) {}; + TBool operator == (const TOtgObservedEvent&other) {return(other.iType==iType && other.iValue==iValue);}; + + // getters + TWatcherNotifyType GetType() {return(iType);}; + TInt GetValue() {return(iValue);}; +private: + TWatcherNotifyType iType; + TInt iValue; + }; + + +/* OTG generic mixin. fires when otg event/state recieved - the Base class auto re-issues + * the request after handling the event by calling IssueAgain() + */ +class MOtgNotificationHandler + { +public: + virtual void HandleEvent(TWatcherNotifyType aType, TInt aNotificationValue)=0; + }; + + +/* Sets up and then Collects notifications the user wanted + * Become active when the last event we wanted fires + */ +class CNotifyCollector : public MOtgNotificationHandler + { +public: + CNotifyCollector(TRequestStatus &aStatus); + virtual ~CNotifyCollector(); + + // Create and start the observers + void CreateObserversL(COtgRoot &aOtgDriver); + // Stop and destroy the observers + void DestroyObservers(); + + // add an object to the Q + void AddRequiredNotification(const TWatcherNotifyType aType, TInt aValue); + + // Add an event to the list of events that indicates an instant failure + // (e.g. the B-Device becoming configured during a short-circuit role swap) + void AddFailureNotification(const TWatcherNotifyType aType, TInt aValue); + + /* Ppecify a step timeout in MILLISECONDS */ + void AddStepTimeout(TInt aTimeoutMs) { + AddRequiredNotification(EWatcherTimeouts, aTimeoutMs);}; + + void ClearAllEvents(TBool aClearRecieved =ETrue, TBool aClearRequired =ETrue); + + + TBool EventReceivedAlready(const TOtgObservedEvent &aEvent); + + // from MOtgNotificationHandler + // ... process the event, if all the needed events are satisfied, complete the object + void HandleEvent(TWatcherNotifyType aType, TInt aNotificationValue); + + // getters + CNotifyWatcherBase* GetWatcher(TWatcherNotifyType aType); + + TInt DurationElapsed(); + +private: + void AddRequiredOrFailureNotification(TWatcherNotifyType aType, TInt aValue, TBool aEventMeansFailure); + TBool IsFailureEvent(TOtgObservedEvent& aEvent); + + void CompleteStep(TInt aCompletionCode); + +private: + TRequestStatus &iStatusStep; // KTestCaseWatchdogTO = failure, the test-step waits on this. + + RArray iNotifyObjects; // observers + + RArray iRequiredEvents; + RArray iReceivedEvents; + RArray iFailureEvents; + + // duration timer + TTime iTimeStarted; + }; + + +/* ----------------------------------------------------------------------------------------------- + * OTG Notification handler Base (Generic). We call these notification watchers, because they abstract + * OTG Messages, OTG Events, OTG States or a Watchdog timeout + */ +class CNotifyWatcherBase : public CActive + { +public: + virtual ~CNotifyWatcherBase() {LOG_FUNC }; + + virtual void StartWatching(TInt aInterval) {LOG_FUNC TInt n(aInterval); IssueAgain(); SetActive(); }; + // getter + TWatcherNotifyType GetType() {return(iWatchType);}; + +protected: + CNotifyWatcherBase (MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aRoot) : + iOtgRoot(aRoot), + iWatchType(aWatchType), + iHandler(aHandler), + CActive(EPriorityStandard) { CActiveScheduler::Add(this); }; + + // from CActive + void RunL(); + + // override in child + +public: + virtual TInt GetEventValue() =0; + virtual TInt IssueAgain() =0; // override + virtual void DisplayEvent() =0; + +protected: + MOtgNotificationHandler & iHandler; + COtgRoot &iOtgRoot; // driver + TWatcherNotifyType iWatchType; + }; + + +//----------------------------------------------------------------------------------------- +// watchdog watcher, +// this watcher converts a CTimer event into a Notification, NOTE: it does not re-Issue the timer +class COtgWatchdogWatcher : public CNotifyWatcherBase + { + public: + static COtgWatchdogWatcher* NewL(MOtgNotificationHandler &wdHandler, + const TWatcherNotifyType aWatchType, + COtgRoot &aOtgRoot); + void ConstructL(); + virtual ~COtgWatchdogWatcher() {LOG_FUNC ;Cancel();}; + + void StartTimer(TInt aIntervalMs); + void StartWatching(TInt aIntervalMs) {StartTimer(aIntervalMs); }; + + + + TInt IssueAgain() { LOG_FUNC ASSERT(0); return(0);}; + void DoCancel() {LOG_FUNC ;iTimer.Cancel();}; + void DisplayEvent() {LOG_FUNC ASSERT(0); }; // should never fire this + TInt GetEventValue() {return(iIntervalMs);}; + void StepExpired(TInt aInterval); + +protected: + COtgWatchdogWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + // from CNotifyWatcherBase + void RunL(); + +protected: + TInt iIntervalMs; + RTimer iTimer; + }; + + +/*-------------------------------------------------------------------------------------------- + * STATE Watcher + * Like the other OTG watchers, this watcher will renew (resubscribe) to the relevant notification + * again after it has fired. + */ +class COtgStateWatcher : public CNotifyWatcherBase + { +public: + static COtgStateWatcher* NewL(MOtgNotificationHandler &wdHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot); + void ConstructL() {}; + + virtual ~COtgStateWatcher() {LOG_FUNC Cancel(); }; + + TInt IssueAgain() { iOtgRoot.otgQueueOtgStateRequest(iState , iStatus); return(ETrue);}; + void DisplayEvent(); + + TInt GetEventValue() {return(iState);}; + + void DoCancel() {LOG_FUNC iOtgRoot.otgCancelOtgStateRequest();}; + +protected: + COtgStateWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + + RUsbOtgDriver::TOtgState iState; + }; + + +//--------------------------------------- +// EVENT Watcher +class COtgEventWatcher : public CNotifyWatcherBase + { +public: + static COtgEventWatcher* NewL(MOtgNotificationHandler &wdHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot); + void ConstructL() {}; + virtual ~COtgEventWatcher() {LOG_FUNC Cancel(); }; + + TInt IssueAgain() { iOtgRoot.otgQueueOtgEventRequest(iEvent , iStatus); return(ETrue);}; + void DisplayEvent(); + TInt GetEventValue() {return(iEvent);}; + void DoCancel() { LOG_FUNC iOtgRoot.otgCancelOtgEventRequest();}; + +protected: + COtgEventWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + + RUsbOtgDriver::TOtgEvent iEvent; + }; + + +//--------------------------------------- +// MESSAGE Watcher +class COtgMessageWatcher : public CNotifyWatcherBase + { +public: + static COtgMessageWatcher* NewL(MOtgNotificationHandler &wdHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot); + void ConstructL() {}; + virtual ~COtgMessageWatcher() {LOG_FUNC Cancel(); }; + + TInt IssueAgain() { iOtgRoot.otgQueueOtgMessageRequest(iMessage, iStatus); return(ETrue);}; + void DisplayEvent(); + TInt GetEventValue() {return(iMessage);}; + void DoCancel() {LOG_FUNC iOtgRoot.otgCancelOtgMessageRequest();}; + +protected: + COtgMessageWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + + RUsbOtgDriver::TOtgMessage iMessage; + }; + +// Client state watcher +class CPeripheralStateWatcher : public CNotifyWatcherBase + { +public: + static CPeripheralStateWatcher* NewL(MOtgNotificationHandler &wdHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot); + void ConstructL() {}; + virtual ~CPeripheralStateWatcher() {LOG_FUNC Cancel(); }; + + TInt IssueAgain() { iOtgRoot.otgQueuePeripheralStateRequest(iPeripheralState, iStatus); return(ETrue);}; + void DisplayEvent(); + TInt GetEventValue() {return(iPeripheralState);}; + void DoCancel() {LOG_FUNC iOtgRoot.otgCancelPeripheralStateRequest();}; + +protected: + CPeripheralStateWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + + TUint iPeripheralState; // *usually* to be interpreted as TUsbcDeviceState, see RDevUsbcClient::AlternateDeviceStatusNotify + }; + +// Client state watcher +class CAConnectionIdleWatcher : public CNotifyWatcherBase + { +public: + static CAConnectionIdleWatcher* NewL(MOtgNotificationHandler &wdHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot); + void ConstructL() {}; + virtual ~CAConnectionIdleWatcher() {LOG_FUNC Cancel(); }; + + TInt IssueAgain() { iOtgRoot.otgQueueAConnectionIdleRequest(iAConnectionIdle, iStatus); return(ETrue);}; + void DisplayEvent(); + TInt GetEventValue() {return(iAConnectionIdle);}; + void DoCancel() {LOG_FUNC iOtgRoot.otgCancelAConnectionIdleRequest();}; + +protected: + CAConnectionIdleWatcher(MOtgNotificationHandler &aHandler, const TWatcherNotifyType aWatchType, COtgRoot &aOtgRoot) : + CNotifyWatcherBase(aHandler, aWatchType, aOtgRoot) + {}; + + void RunL(); // From CActive + + RUsbOtgDriver::TOtgConnection iAConnectionIdle; + }; + + +#endif // B2BWATCHERS_H