#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