kerneltest/e32test/usbho/t_usbdi/inc/ControlTransferRequests.h
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/usbho/t_usbdi/inc/ControlTransferRequests.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1127 @@
+#ifndef __CONTROL_TRANSFER_REQUESTS_H
+#define __CONTROL_TRANSFER_REQUESTS_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:
+* @file ControlTransferRequests.h
+* @internalComponent
+* 
+*
+*/
+
+
+
+#include <e32base.h>
+#include <e32ver.h>
+#include <d32usbdi.h>
+
+namespace NUnitTesting_USBDI
+	{
+
+//These values MUST be kept in line with each other
+const _LIT8(KNumberFormatString, "%08d");
+const TUint KNumberStringLength = 8;
+
+//These values MUST be kept in line with each other
+const _LIT8(KTwoNumberFormatString, "%08d%08d");
+const TUint KTwoNumberStringLength = 16;
+
+//These values MUST be kept in line with each other
+const _LIT8(KSplitWriteNumberFormatString, "%08d%08d%08d");
+const TUint KSplitWriteNumberStringLength = 24;
+const TUint KNumSplitWriteSections = 3;
+
+//These values MUST be kept in line with each other
+const _LIT8(KClientPassString, "PASS");
+const _LIT8(KClientFailString, "FAIL");
+const TUint KPassFailStringLength = 4;
+
+const TUint KTestBufferLength = 32; //must be more than KPassFailStringLength
+
+const TUint KMaxSendSize = 2048;	
+
+
+
+// ------------- bRequest -----------------
+const TUint8 KVendorEmptyRequest(0x00);
+const TUint8 KVendorPutPayloadRequest(0x01);
+const TUint8 KVendorGetPayloadRequest(0x02);
+const TUint8 KVendorGetRecordedNumBytesReadInPayloadRequest (0x03);
+const TUint8 KVendorGetRecordedNumBytesWrittenInPayloadRequest (0x04);
+const TUint8 KVendorStallRequest(0x05);
+const TUint8 KVendorRemoteWakeupRequest(0x06);
+const TUint8 KVendorReconnectRequest(0x07);
+const TUint8 KVendorWriteToEndpointRequest(0x08);
+const TUint8 KVendorPatternWriteToEndpointRequest(0x09);
+const TUint8 KVendorCancelWriteToEndpointRequest(0x0a);
+const TUint8 KVendorPatternWriteSynchronousToEndpointRequest(0x0b);
+const TUint8 KVendorPatternWriteSynchronousToAndHaltEndpointRequest(0x0c);
+const TUint8 KVendorStringValidationRequest(0x0d);
+const TUint8 KVendorWriteSynchronousCachedReadRequest(0x0e);
+const TUint8 KVendorWriteCachedReadRequest(0x0f);
+const TUint8 KVendorRepeatedPatternWriteDataRequest (0x10);
+const TUint8 KVendorSplitWriteSynchronousCachedReadRequest(0x11);
+const TUint8 KVendorReadFromEndpointRequest(0x12);
+const TUint8 KVendorReadUntilShortFromEndpointRequest(0x13);
+const TUint8 KVendorReadFromAndHaltEndpointRequest(0x14);
+const TUint8 KVendorRepeatedReadAndValidateDataRequest(0x15);
+const TUint8 KVendorRecordedValidationResultRequest (0x16);
+const TUint8 KVendorCancelAnyReadFromEndpointRequest (0x17);
+const TUint8 KVendorTestCasePassed(0x20);
+const TUint8 KVendorTestCaseFailed(0x21);
+const TUint8 KVendorUnrespondRequest(0x22);
+const TUint8 KVendorDisconnectDeviceAThenConnectDeviceCRequest(0x23);
+const TUint8 KVendorDisconnectDeviceCThenConnectDeviceARequest(0x24);
+
+// class specific
+// audio
+const TUint8 KAudioClassSetCur(0x01);
+
+// ------------- bmRequestType -----------------
+
+// D7: Data phase transfer direction
+const TUint8 KHostToDevice(0x00);
+const TUint8 KDeviceToHost(0x80);
+
+// D6..5: Type
+const TUint8 KTypeStandard(0x00);
+const TUint8 KTypeClass(0x20);
+const TUint8 KTypeVendor(0x40);
+
+// D4..0: Recipient
+const TUint8 KRecipientDevice(0x00);
+const TUint8 KRecipientInterface(0x01);
+const TUint8 KRecipientEndpoint(0x02);
+const TUint8 KRecipientOther(0x03);
+
+// ------------------------------------------------------------------
+
+// The customised requests (i.e. non standard control requests)
+
+// ------------------------------------------------------------------
+	
+/**
+This policy class represents the basic control request setup packet
+that the user will derive from and customise to describe usable control requests
+otherwise with the default values it represents a 'standard device request'
+*/
+class TControlSetupPacket : public ::RUsbInterface::TUsbTransferRequestDetails
+	{
+protected:
+	TControlSetupPacket()
+		{
+		iRequestType = 0;
+		iRequest = 0;
+		iValue = 0;
+		iIndex = 0;
+		}
+	};
+
+/**
+This class represents a control request to the client that does not request 
+data from the client.  It merely instructs the client
+*/
+class TEmptyRequest : public TControlSetupPacket
+	{
+protected:
+	TEmptyRequest()
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		iRequest = KVendorEmptyRequest;
+		}
+	};
+
+/**
+ */
+ class TDataSendRequest : public TControlSetupPacket
+ 	{
+ 	friend class CEp0Transfer;
+
+ protected:
+ 	TDataSendRequest()
+ 		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		}
+	
+ 	explicit TDataSendRequest(const TDesC8& aData)
+ 		{
+ 		iRequestType |= KHostToDevice;
+ 		iRequestType |= KTypeVendor;
+ 		iSendData.Copy(aData);
+ 		}
+
+ 	explicit TDataSendRequest(const TDesC16& aData)
+ 		{
+ 		iRequestType |= KHostToDevice;
+ 		iRequestType |= KTypeVendor;
+ 		iSendData.Copy(aData);
+ 		}
+ 	protected:
+ 	TBuf8<KMaxSendSize> iSendData;
+ 	};
+ 		
+		
+/**
+*/
+class TClassDataSendRequest : public TControlSetupPacket
+	{
+	friend class CEp0Transfer;
+
+protected:
+	explicit TClassDataSendRequest(const TDesC8& aData)
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeClass;
+		iSendData.Copy(aData);
+		}
+
+	explicit TClassDataSendRequest(const TDesC16& aData)
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeClass;
+		iSendData.Copy(aData);
+		}
+	protected:
+	TBuf8<KMaxSendSize> iSendData;
+	};
+
+
+/**
+This class represents a control request to the client that requests some data 
+in response to the request
+*/
+class TDataRecvRequest : public TControlSetupPacket
+	{
+	friend class CEp0Transfer;
+
+protected:
+	explicit TDataRecvRequest(TDes8& aData) : iRecvData(aData)
+		{
+		iRequestType |= KDeviceToHost;
+		iRequestType |= KTypeVendor;
+		}
+
+protected:
+	TDes8& iRecvData;
+	};
+
+
+/**
+*/
+class TDescriptorGetRequest : public TDataRecvRequest
+	{
+public:
+	/**
+	Constructor, build a request to fetch a descriptor from the device
+	@param aTypeAndIndex the type of the descriptor and the index
+	@param aLanguage Id the identity of the language
+	@param aData the symbian descriptor to hold the usb descriptor data 
+	*/
+	
+	TDescriptorGetRequest(TUint16 aTypeAndIndex,TUint16 aLanguageId,TDes8& aData)
+	:	TDataRecvRequest(aData)
+		{
+		iRequestType = 0; // Will overwrite KTypeVendor in base class
+		iRequestType |= KDeviceToHost;	
+		iRequest = 0x06; // Standard device GET_DESCRIPTOR
+		iValue = aTypeAndIndex;
+		iIndex = aLanguageId;
+		}
+	};
+
+	
+/**
+This class represents an empty request that is directed at the device.
+i.e. a request that does not require data from the client device
+*/
+class TEmptyDeviceRequest : public TEmptyRequest
+	{
+public:
+	TEmptyDeviceRequest()
+		{
+		iRequestType |= KRecipientDevice;
+		}
+	};
+
+/** 
+This class represents an empty request that is directed at the interface.
+i.e. a request that does not require data from the client interface
+*/
+class TEmptyInterfaceRequest : public TEmptyRequest
+	{
+public:
+	explicit TEmptyInterfaceRequest(TUint16 aInterfaceNumber)
+		{
+		iRequestType |= KRecipientInterface;
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+/**
+This class represents a device directed request that send a payload
+*/
+class TDevicePutPayloadRequest : public TDataSendRequest
+	{
+public:
+	TDevicePutPayloadRequest(const TDesC8& aData) : TDataSendRequest(aData)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorPutPayloadRequest;
+		iValue = 0;
+		iIndex = 0;
+		}
+	};
+	
+/**
+This class represents a device directed request that retrieves a payload
+from the client device
+*/
+class TDeviceGetPayloadRequest : public TDataRecvRequest
+	{
+public:
+	explicit TDeviceGetPayloadRequest(TDes8& aData) : TDataRecvRequest(aData)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorGetPayloadRequest;
+		iValue = 0;
+		iIndex = 0;
+		}
+	};
+	
+/**
+This class represents a device directed request that retrieves a payload
+from the client device containing the number of bytes read on an endpoint 
+performing a 'Repeated Read'. 
+*/
+class TInterfaceGetRecordedNumBytesReadInPayload : public TDataRecvRequest
+	{
+public:
+	explicit TInterfaceGetRecordedNumBytesReadInPayload(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,TDes8& aData) : TDataRecvRequest(aData)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorGetRecordedNumBytesReadInPayloadRequest;
+		iValue = aReadEndpointNumber;
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+/**
+This class represents a device directed request that retrieves a payload
+from the client device containing the number of bytes written on an endpoint 
+performing a 'Repeated Write'. 
+*/
+class TInterfaceGetRecordedNumBytesWrittenInPayload : public TDataRecvRequest
+	{
+public:
+	explicit TInterfaceGetRecordedNumBytesWrittenInPayload(const TUint16 aInterfaceNumber,const TUint8 aWriteEndpointNumber,TDes8& aData) : TDataRecvRequest(aData)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorGetRecordedNumBytesWrittenInPayloadRequest;
+		iValue = aWriteEndpointNumber;
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+
+
+/**
+This class represents an interface directed request that sends a payload
+*/
+class TInterfacePutPayloadRequest : public TDataSendRequest
+	{
+public:
+	TInterfacePutPayloadRequest(TUint16 aInterfaceNumber,const TDesC8& aData) : TDataSendRequest(aData)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorPutPayloadRequest;
+		iValue = 0;
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+/**
+This class represents a device directed request that retrieves a payload
+from the client device
+*/
+class TInterfaceGetPayloadRequest : public TDataRecvRequest
+	{
+public:
+	explicit TInterfaceGetPayloadRequest(TUint16 aInterfaceNumber,TDes8& aData) : TDataRecvRequest(aData)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorGetPayloadRequest;
+		iValue = 0;
+		iIndex = aInterfaceNumber;
+		}
+	};
+
+/**
+This class represents a control request to stall a specified endpoint
+*/
+class TInterfaceEndpointBaseRequest : public TEmptyRequest
+	{
+public:
+	/**
+	Constructor, build a request containing a specified endpoint and a specified interface
+	@param aEndpointNumber the endpoint to use
+	@param aInterfaceNumber the interface to use
+	*/
+	
+	TInterfaceEndpointBaseRequest(TUint16 aEndpointNumber,TUint16 aInterfaceNumber)
+	: TEmptyRequest()
+		{
+		iRequestType |= KRecipientInterface;
+		iValue = aEndpointNumber;
+		iIndex = aInterfaceNumber;
+		}
+	};
+
+/**
+This class represents a control request to stall a specified endpoint
+*/
+class TStallEndpointRequest : public TInterfaceEndpointBaseRequest
+	{
+public:
+	/**
+	Constructor, build a request to stall a specified endpoint
+	@param aEndpointNumber the endpoint to stall
+	*/
+	
+	TStallEndpointRequest(TUint16 aEndpointNumber,TUint16 aInterfaceNumber)
+	: TInterfaceEndpointBaseRequest(aEndpointNumber, aInterfaceNumber)
+		{
+		iRequest = KVendorStallRequest;
+		}
+	};
+
+/**
+This class represents a control request to use a validation previously recorded in the endpoint
+to update the interface's PASS\FAIL string.
+*/
+class TRecordedValidationResultRequest : public TInterfaceEndpointBaseRequest
+	{
+public:
+	/**
+	Constructor, build a request to update the interface's PASS\FAIL 
+	string using a previously recorded validation.
+	@param aEndpointNumber the endpoint to from which to retrieve the previously recorded validation
+	*/
+	
+TRecordedValidationResultRequest(TUint16 aEndpointNumber,TUint16 aInterfaceNumber)
+	: TInterfaceEndpointBaseRequest(aEndpointNumber, aInterfaceNumber)
+		{
+		iRequest = KVendorRecordedValidationResultRequest;
+		}
+	};
+
+/**
+This class represents a control request to stall a specified endpoint
+*/
+class TEndpointCancelWriteRequest : public TInterfaceEndpointBaseRequest
+	{
+public:
+	/**
+	Constructor, build a request to stall a specified endpoint
+	@param aEndpointNumber the endpoint to stall
+	*/
+	
+	TEndpointCancelWriteRequest(TUint16 aEndpointNumber,TUint16 aInterfaceNumber)
+	: TInterfaceEndpointBaseRequest(aEndpointNumber, aInterfaceNumber)
+		{
+		iRequest = KVendorCancelWriteToEndpointRequest;
+		}
+	};
+
+/**
+This class represents a control request to stall a specified endpoint
+*/
+class TEndpointCancelReadRequest : public TInterfaceEndpointBaseRequest
+	{
+public:
+	/**
+	Constructor, build a request to stall a specified endpoint
+	@param aEndpointNumber the endpoint to stall
+	*/
+	
+	TEndpointCancelReadRequest(TUint16 aEndpointNumber,TUint16 aInterfaceNumber)
+	: TInterfaceEndpointBaseRequest(aEndpointNumber, aInterfaceNumber)
+		{
+		iRequest = KVendorCancelAnyReadFromEndpointRequest;
+		}
+	};
+
+/**
+This class represents a control request to the device to initiate a remote
+wake-up after the supplied interval has elapsed.
+*/
+class TRemoteWakeupRequest : public TEmptyRequest
+	{
+public:
+	explicit TRemoteWakeupRequest(TUint16 aWakeupInterval)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorRemoteWakeupRequest;
+		iValue = aWakeupInterval;
+		}
+	};
+
+/**
+This class represents a control request to the device to reconnect to the host after 
+the supplied interval has elapsed
+*/
+class TReconnectRequest : public TEmptyRequest
+	{
+public:
+	explicit TReconnectRequest(TUint16 aReconnectInterval)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorReconnectRequest;
+		iValue = aReconnectInterval;		
+		}
+	};
+	
+/**
+This class represents a control request to the device to disconnect device A and connect 
+device C to the host 
+*/
+class TDisconnectDeviceAThenConnectDeviceCRequest : public TEmptyRequest
+	{
+public:
+	/**
+	Constructor, build a request that informs the client device of a successful test case status
+	*/
+	
+	TDisconnectDeviceAThenConnectDeviceCRequest()
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorDisconnectDeviceAThenConnectDeviceCRequest;
+		iValue = KErrNone;
+		}
+	};
+
+/**
+This class represents a control request to the device to disconnect device C and connect 
+device A to the host 
+*/
+class TDisconnectDeviceCThenConnectDeviceARequest : public TEmptyRequest
+	{
+public:
+	/**
+	Constructor, build a request that informs the client device of a successful test case status
+	*/
+	
+	TDisconnectDeviceCThenConnectDeviceARequest()
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorDisconnectDeviceCThenConnectDeviceARequest;
+		iValue = KErrNone;
+		}
+	};
+	
+/**
+This class represents an instruction to the client to write the data 
+supplied to an endpoint that is specified
+*/
+class TEndpointWriteRequest : public TDataSendRequest
+	{
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to write data
+	to a specified endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aData the data to write to that endpoint
+	*/
+	
+	TEndpointWriteRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TDesC8& aData) : TDataSendRequest(aData)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorWriteToEndpointRequest;
+		iValue = aEndpointNumber;
+		iIndex = aInterfaceNumber;
+		}
+	};
+
+/**
+This class represents an instruction to the client to write specified data a number of times 
+on a given endpoint
+*/
+class TEndpointPatternWriteRequest : public TDataSendRequest
+ 	{
+ 	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to write specified data
+	to an endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aData the data pattern to use when writing to that endpoint
+	@param aNumBytes the number of bytes to write using that data pattern
+	*/
+	TEndpointPatternWriteRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TDesC8& aData,const TUint aNumBytes)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorPatternWriteToEndpointRequest;
+		iValue = aEndpointNumber; 
+		iIndex = aInterfaceNumber;
+
+		iSendData.Zero();
+ 		iSendData.Format(KNumberFormatString, aNumBytes);
+ 		iSendData.Append(aData);
+ 		}
+ 	};
+
+	
+		
+/**
+This class represents an instruction to the client to synchronously write specified data a number of times 
+on a given endpoint
+*/
+class TEndpointPatternSynchronousWriteRequest : public TEndpointPatternWriteRequest
+ 	{
+ 	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to write specified data
+	to an endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aData the data pattern to use when writing to that endpoint
+	@param aNumBytes the number of bytes to write using that data pattern
+	*/
+	TEndpointPatternSynchronousWriteRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TDesC8& aData,const TUint aNumBytes)
+	: TEndpointPatternWriteRequest(aInterfaceNumber,aEndpointNumber,aData,aNumBytes)
+		{
+		iRequest = KVendorPatternWriteSynchronousToEndpointRequest;
+		}
+ 	};
+
+	
+		
+/**
+This class represents an instruction to the client synchronously to write specified data a number of times 
+on a given endpoint and then halt that endpoint
+*/
+class TEndpointPatternSynchronousWriteAndHaltRequest : public TEndpointPatternSynchronousWriteRequest
+ 	{
+ 	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to write specified data
+	to an endpoint and then halt that endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aData the data pattern to use when writing to that endpoint
+	@param aNumBytes the number of bytes to write using that data pattern
+	*/
+	TEndpointPatternSynchronousWriteAndHaltRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TDesC8& aData,const TUint aNumBytes)
+	: TEndpointPatternSynchronousWriteRequest(aInterfaceNumber, aEndpointNumber, aData, aNumBytes)
+		{
+		iRequest = KVendorPatternWriteSynchronousToAndHaltEndpointRequest;
+ 		}
+ 	};
+
+/**
+This class represents an instruction to the client to validate data read on an endpoint with specified data 
+on a given endpoint
+*/
+ class TEndpointStringValidationRequest : public TEndpointPatternWriteRequest
+ 	{
+ 	friend class CEp0Transfer;
+
+ public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to 
+	verify data on an endpoint using the data pattern provided
+	@param aInterfaceNumber the number of the interface which has this endpoint
+	@param aEndpointNumber the number of the endpoint to use (a pipe must be open on this endpoint)
+	@param aData the data pattern to use when verifying on that endpoint
+	@param aNumBytes the number of bytes to write using that data pattern	*/
+	TEndpointStringValidationRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TDesC8& aData,const TUint aNumBytes)
+ 	: TEndpointPatternWriteRequest(aInterfaceNumber,aEndpointNumber,aData,aNumBytes)
+ 		{
+ 		iRequest = KVendorStringValidationRequest;
+		}
+ 	};
+	 	
+	
+		
+/**
+This class represents an instruction to the client to write back data just read.
+*/
+class TWriteSynchronousCachedReadDataRequest : public TControlSetupPacket
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to use the data
+	just read on one endpoint to send back on another.
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aReadEndpointNumber the number of the endpoint that has just been read from (a pipe must be open on this endpoint)
+	@param aWriteEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	*/
+	TWriteSynchronousCachedReadDataRequest(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,const TUint8 aWriteEndpointNumber)
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorWriteSynchronousCachedReadRequest;
+		iValue = aReadEndpointNumber << 8 | aWriteEndpointNumber; 
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+/**
+This class represents an instruction to the client to write back data just read.
+*/
+class TWriteCachedReadDataRequest : public TWriteSynchronousCachedReadDataRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to use the data
+	just read on one endpoint to send back on another.
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aReadEndpointNumber the number of the endpoint that has just been read from (a pipe must be open on this endpoint)
+	@param aWriteEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	*/
+	TWriteCachedReadDataRequest(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,const TUint8 aWriteEndpointNumber)
+	: TWriteSynchronousCachedReadDataRequest(aInterfaceNumber, aReadEndpointNumber, aWriteEndpointNumber)
+		{
+		iRequest = KVendorWriteCachedReadRequest;
+		}
+	};
+	
+	
+/**
+This class represents an instruction to the client to write back data just read - in sections.
+*/
+class TSplitWriteCachedReadDataRequest : public TDataSendRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to use the data
+	just read on one endpoint to send back on another.
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aReadEndpointNumber the number of the endpoint that has just been read from (a pipe must be open on this endpoint)
+	@param aWriteEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	*/
+	TSplitWriteCachedReadDataRequest(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,const TUint8 aWriteEndpointNumber,const TUint aNumBytes[KNumSplitWriteSections])
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorSplitWriteSynchronousCachedReadRequest;
+		iValue = aReadEndpointNumber << 8 | aWriteEndpointNumber; 
+		iIndex = aInterfaceNumber;
+
+		iSendData.Zero();
+		for(TUint i = 0; i<KNumSplitWriteSections; ++i)
+			{
+			TBuf8<KNumberStringLength> buf;
+			buf.Format(KNumberFormatString, aNumBytes[i]);
+			iSendData.Append(buf);
+			}
+ 		}
+	};
+	
+/**
+This class represents an instruction to the client to write back data just read - in sections.
+*/
+class TRepeatedWriteDataRequest : public TDataSendRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to perform 
+	a repeated read using the data as a pattern to validate the data as it arrives.
+	Constructor, build a request that instructs an interface on the client device to perform 
+	a repeated write using the data as a pattern.
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aReadEndpointNumber the number of the endpoint that has just been read from (a pipe must be open on this endpoint)
+	@param aData the data pattern to be used for validation
+	@param aNumBytesPerRead the number of bytes to read at each 'Read'
+	@param aTotalNumBytes the total number of bytes to read (over all 'Read's)
+	*/
+TRepeatedWriteDataRequest(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,const TDesC8& aDataPattern,const TUint aNumBytesPerRead,const TUint aTotalNumBytes)
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorRepeatedPatternWriteDataRequest;
+		iValue = aReadEndpointNumber; 
+		iIndex = aInterfaceNumber;
+
+		iSendData.Zero();
+		TBuf8<KTwoNumberStringLength> buf;
+		buf.Format(KTwoNumberFormatString, aNumBytesPerRead, aTotalNumBytes);
+		iSendData.Append(buf);
+		iSendData.Append(aDataPattern);
+		}
+	};
+	
+	 	
+	
+/**
+This class represents an instruction to the client to read a number of bytes of data 
+on an the endpoint.
+*/
+class TEndpointReadRequest : public TControlSetupPacket
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to read a specified amount data
+	on the specified endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aNumBytes the amount of data to read on that endpoint
+	*/
+	TEndpointReadRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TUint aNumBytes)
+		{
+		iRequestType |= KHostToDevice;
+		iRequestType |= KTypeVendor;
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorReadFromEndpointRequest;
+		iValue = aEndpointNumber; 
+		iIndex = aInterfaceNumber;
+
+		iReadSpecificationData.Zero();
+		iReadSpecificationData.Format(KNumberFormatString, aNumBytes);
+		}
+
+protected:
+	TBuf8<KNumberStringLength> iReadSpecificationData;
+	};
+
+/**
+This class represents an instruction to the client to read a number of bytes of data 
+on an the endpoint. Reading will complete early if a short packet is detected.
+*/
+class TEndpointReadUntilShortRequest : public TEndpointReadRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to read the data
+	on the specified endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aNumBytes the amount of data to read on that endpoint (if a short packet does not arrive sooner)
+	*/
+	TEndpointReadUntilShortRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TUint aNumBytes)
+	: TEndpointReadRequest(aInterfaceNumber, aEndpointNumber, aNumBytes)
+		{
+		iRequest = KVendorReadUntilShortFromEndpointRequest;
+		}
+	};
+
+/**
+This class represents an instruction to the client to read a number of bytes of data 
+on an the endpoint, and then, when the specified number of bytes have been read, to stall the endpoint.
+*/
+class TEndpointReadAndHaltRequest : public TEndpointReadRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to read the data
+	on the specified endpoint
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aEndpointNumber the number of the endpoint to write to (a pipe must be open on this endpoint)
+	@param aNumBytes the amount of data to read on that endpoint (if a short packet does not arrive sooner)
+	*/
+	TEndpointReadAndHaltRequest(TUint16 aInterfaceNumber,TUint16 aEndpointNumber,const TUint aNumBytes)
+	: TEndpointReadRequest(aInterfaceNumber, aEndpointNumber, aNumBytes)
+		{
+		iRequest = KVendorReadFromAndHaltEndpointRequest;
+		}
+	};
+
+/**
+This class represents an instruction to the client to write back data just read - in sections.
+*/
+class TRepeatedReadAndValidateDataRequest : public TRepeatedWriteDataRequest
+	{
+	friend class CEp0Transfer;
+
+public:
+	/**
+	Constructor, build a request that instructs an interface on the client device to perform 
+	a repeated read using the data as a pattern to validate the data as it arrives.
+	@param aInterfaceNumber the number of the interface which has this endpoint to write to
+	@param aReadEndpointNumber the number of the endpoint that has just been read from (a pipe must be open on this endpoint)
+	@param aData the data pattern to be used for validation
+	@param aNumBytesPerRead the number of bytes to read at each 'Read'
+	@param aTotalNumBytes the total number of bytes to read (over all 'Read's)
+	*/
+TRepeatedReadAndValidateDataRequest(const TUint16 aInterfaceNumber,const TUint8 aReadEndpointNumber,const TDesC8& aDataPattern,const TUint aNumBytesPerRead,const TUint aTotalNumBytes)
+: TRepeatedWriteDataRequest(aInterfaceNumber,aReadEndpointNumber,aDataPattern,aNumBytesPerRead,aTotalNumBytes)		
+		{
+		iRequest = KVendorRepeatedReadAndValidateDataRequest;
+		}
+	};
+	
+	 	
+/**
+This class represents a request that requests the client device
+to negatively acknowledge the request
+*/
+class TNakRequest : public TEmptyRequest
+	{
+public:
+	/**
+	Constructor, build a request that instructs an interface to continually NAK the request
+	@param aInterfaceNumber the interface number
+	*/
+	
+	explicit TNakRequest(TUint16 aInterfaceNumber)
+		{
+		iRequestType |= KRecipientInterface;
+		iRequest = KVendorUnrespondRequest;
+		iIndex = aInterfaceNumber;
+		}
+	};
+	
+/**
+This class represents a control request to the device to indicate that test case
+has successfully completed and to disconnect the device
+*/
+class TTestCasePassed : public TEmptyRequest
+	{
+public:
+	/**
+	Constructor, build a request that informs the client device of a successful test case status
+	*/
+	
+	TTestCasePassed()
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorTestCasePassed;
+		iValue = KErrNone;
+		}
+	};
+	
+/**
+This class represents a control request to the device of an unsuccessful test case execution
+and to complete the device side test case with the supplied error and error message
+*/
+class TTestCaseFailed : public TDataSendRequest	
+	{
+public:
+	/**
+	Constructor, build a request that informs the client device of an unsuccessful test case status
+	@param aError the error that the host side test case reports
+	@param aErrorMsg the message text (non-unicode) for the client to display when this request has been received 
+	*/
+	
+	TTestCaseFailed(TInt aError,const TDesC8& aErrorMsg) : TDataSendRequest(aErrorMsg)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorTestCaseFailed;
+		iValue = -aError; // Invert the error as symbian system errors are negative
+		}
+	
+	/**
+	Constructor, build a request that informs the client device of an unsuccessful test case status
+	@param aError the error that the host side test case reports
+	@param aErrorMsg the message text (unicode) for the client to display when this request has been received 
+	*/
+	
+	TTestCaseFailed(TInt aError,const TDesC16& aErrorMsg) : TDataSendRequest(aErrorMsg)
+		{
+		iRequestType |= KRecipientDevice;
+		iRequest = KVendorTestCaseFailed;
+		iValue = -aError; // Invert the error as symbian system errors are negative
+		}
+	};
+
+
+/**
+This class represents the SET_CUR audio class control request
+*/
+class TSetCurRequest : public TClassDataSendRequest
+	{
+public:
+	explicit TSetCurRequest(const TDesC8& aData, const TUint aEndpointAddress) : TClassDataSendRequest(aData) //TUint16 aSamplingFrequency)
+		{
+		iRequestType |= KRecipientEndpoint;
+		iRequest = KAudioClassSetCur;		
+		iValue = 0x0100;
+		iIndex = aEndpointAddress;
+		}
+	};
+
+	
+/**
+This class describes an observer to the Ep0 control transfer
+*/
+class MCommandObserver
+	{
+public:
+	/**
+	Called when an endpoint zero test command transfer has completed
+	@param aCompletionCode the completion code of the asynchronous transfer to Ep0
+	*/
+	virtual void Ep0TransferCompleteL(TInt aCompletionCode) = 0;
+	};
+
+/**
+This class represents a transfer to a control endpoint 0
+*/
+class CEp0Transfer : public CActive
+	{
+public:
+	/**
+	Constructor, build a test command to send to the connected client
+	@param aToken the token 
+	*/
+	CEp0Transfer(RUsbInterface& aInterface0);
+	
+	/**
+	Destructor
+	*/
+	~CEp0Transfer();
+	
+	/**
+	Send a control transfer request to endpoint zero of the client
+	@param aSetupPacket a control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TEmptyRequest& aSetupPacket,MCommandObserver* aObserver);
+	
+	/**
+	Send a control transfer request to endpoint zero of the client
+	@param aSetupPacket a control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TDataRecvRequest& aSetupPacket,MCommandObserver* aObserver);
+	
+	/**
+	Send a control transfer request to endpoint zero of the client that will also send a payload in data packets
+	@param aSetupPacket a control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TDataSendRequest& aSetupPacket,MCommandObserver* aObserver);
+
+	/**
+	Send a control transfer request to endpoint zero of the client
+	@param aSetupPacket a control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TWriteSynchronousCachedReadDataRequest& aSetupPacket,MCommandObserver* aObserver);
+
+	/**
+	Send a control transfer request to endpoint zero of the client that will also send a payload in data packets
+	@param aSetupPacket a control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TEndpointReadRequest& aSetupPacket,MCommandObserver* aObserver);
+
+	/**
+	Send a class control transfer request to endpoint zero of the client that will also send a payload in data packets
+	@param aSetupPacket a class control request
+	@param aObserver the observer that will be notified of transfer completion
+	*/
+	void SendRequest(TClassDataSendRequest& aSetupPacket,MCommandObserver* aObserver);
+	
+	/**
+	Cancel last SendRequest if still active. This does NOT cancel the active object
+	which must be done separately using the normal 'Cancel' function.
+	*/
+	void CancelSendRequest();
+
+	/**
+	Gets the time the last SendRequest was sent.
+	*/
+	void LastRequestStartTime( TTime& aDuration);
+
+	/**
+	Gets the time the last SendRequest was completed in RunL.
+	*/
+	void LastRequestCompletionTime( TTime& aDuration);
+
+private:
+	
+	/**
+	Currently no way to cancel a single transfer, so not going to try
+	*/
+	void DoCancel();
+
+	/**
+	*/
+	void RunL();
+	
+	/**
+	*/
+	TInt RunError(TInt aError);
+
+private:
+
+	/**
+	The USB interface endpoint zero which receives the command
+	For the test devices modelled 
+	*/
+	RUsbInterface& iUsbInterface0;
+	
+	/**
+	The observer of client responses to host commands (uses-a)
+	*/
+	MCommandObserver* iObserver;
+
+	/**
+	The actual amount of data received by the host from the client
+	in response to a command sent by the host
+	*/
+	TInt iActualLength;
+	
+	/**
+	The flag to indicate if the request sent required the clieent device to answer with
+	some data
+	*/
+	TBool iDataRequest;
+	
+	TBuf8<1> iTemp;
+
+	/**
+	 The time the last SendRequest was sent.
+	 */
+	TTime iRequestTime;
+
+	/**
+	 The time the last SendRequest was completed in RunL
+	 */
+	TTime iCompletionTime;
+	};
+
+
+	}
+
+
+#endif
+