--- /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 <d32otgdi.h> // OTGDI thunk headder (under test)
+#include <d32usbc.h>
+#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<CNotifyWatcherBase*> iNotifyObjects; // observers
+
+ RArray<TOtgObservedEvent> iRequiredEvents;
+ RArray<TOtgObservedEvent> iReceivedEvents;
+ RArray<TOtgObservedEvent> 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