remoteconn_plat/generic_hid_api/inc/hidinterfaces.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 16:03:15 +0300
branchRCL_3
changeset 19 0aa8cc770c8a
permissions -rw-r--r--
Revision: 201032 Kit: 201035

/*
* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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:  Declares main application class.
*
*/



#ifndef C_HIDDRIVER_H
#define C_HIDDRIVER_H

#include <ecom/ecom.h>


class CReportRoot;
class MDriverAccess;
class MTransportLayer;
class CHidDriver;
// ----------------------------------------------------------------------

// Return codes from the Generic HID to Transport layers
//
const TInt KErrHidBase = -8000;

const TInt KErrHidNoDriver = KErrHidBase;           /*!< No driver could be found to handle the request */
const TInt KErrHidSuspended = KErrHidBase - 1;      /*!< Command not handled - driver is suspended */
const TInt KErrHidUnrecognised = KErrHidBase - 2;   /*!< Driver could not understand the data */
const TInt KErrHidUnexpected = KErrHidBase - 3;     /*!< Unsolicited data from the device */
const TInt KErrHidBadChannel = KErrHidBase - 4;     /*!< Channel was not Int or Ctrl type */
const TInt KErrHidPartialSupported = KErrHidBase - 5;     /*!< Partil supported hid device */

// Errors returned by the report translator / generator:
//
const TInt KErrUsageNotFound = KErrHidBase - 10;    //!< Usage page/ID wasn't found in the field
const TInt KErrValueOutOfRange = KErrHidBase - 11;  //!< Value specified is outside the logical range
const TInt KErrNoSpaceInArray = KErrHidBase - 12;   //!< Array field already contains the maximum number of values
const TInt KErrBadControlIndex = KErrHidBase - 13;  //!< Control index exceeds the number of controls in the field

// ACK codes returned by Set/Get requests to the devices
//
const TInt KErrCommandAckBase = -8100;

const TInt KErrAckInvalidReportID = KErrCommandAckBase;         /*!< Invalid report ID */
const TInt KErrAckInvalidParameter = KErrCommandAckBase - 1;    /*!< Invalid or out of range param */
const TInt KErrAckUnknown = KErrCommandAckBase - 2;             /*!< Command failed, but the device can't determine why */
const TInt KErrAckFatal = KErrCommandAckBase - 3;               /*!< The device is in an unrecoverable state and must be restarted */

// Constant for plugin interface:
const TUid KHidDriverPluginInterfaceUid        = { 0x10201d26 };


class THidEvent
    {
    public:
    /**
     * Usage page
     */
    TInt iUsagePage;
    
    /**
     * Keycode
     */
    TInt iKeyCode;
    };

class CHidInputDataHandlingReg: public CBase
    {
       
public:
    /**
     * Two-phased constructor.     
     */
    static CHidInputDataHandlingReg* NewL();

    /**
     * Destructor
     */
     virtual ~CHidInputDataHandlingReg(); 

public:        
        
    /**
     * Check if key event is not allready processed
     *
     * @since S60 v5.0
     * @param aUsagePage a usage page to be checked
     * @param aUsage a usage code to be checked
     * @return true if event is not allready handled
     */
    IMPORT_C TBool  AllowedToHandleEvent(TInt aUsagePage, TInt aUsage);
    
    
    /**
     * Add handled event
     *
     * @since S60 v5.0
     * @param aUsagePage usage page to be handled
     * @param aUsage Usage to be handled
     * @return None.
     */ 
    IMPORT_C void  AddHandledEvent( TInt aUsagePage, TInt aUsage);
    
    /**
     * Reset Array 
     */
    void  Reset();
    
private:
    
    CHidInputDataHandlingReg();
    void ConstructL();

private: 
    
    /**
     * Event array
     * Own.
     */
    CArrayFixFlat<THidEvent>* iEventArray;
    
    };

/**
 *
 *  Transport layer interface class
 *  Interface allowing the generic HID layer to pass data to a Transport layer
 *  All commands are asynchronous.  The results are returned via the
 *
 *  @since S60 v5.0
 */
class MTransportLayer
    {
public:

    /**
     * Request for the country code of the given device.
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return country code.
     */
    virtual TUint CountryCodeL(TInt aConnID) = 0;

    /**
     * Request for the vendor identifier for the given device.
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return vendor id.
     */
    virtual TUint VendorIdL(TInt aConnID) = 0;

    /**
     * Request for the product identifier for the given device.
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return product id.
     */
    virtual TUint ProductIdL(TInt aConnID) = 0;

    /**
     * Request for the current device report protocol. The protocol will be
     * received as a control report via the CHidTransport::DataIn function
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aInterface The interface we want to get the protocol from
     * @return None.
     */
    virtual void GetProtocolL(TInt aConnID,  TUint16 aInterface) = 0;

    /**
     * Request to put the device in the specified protocol
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aValue The requested protocol for the device (boot or report)
     * @param aInterface The interface we want to set the protocol for
     * @return None.
     */
    virtual void SetProtocolL(TInt aConnID, TUint16 aValue,
        TUint16 aInterface) = 0;

    /**
     * Request for a device report. The data will be received as a control report
     * via the CHidTransport::DataIn function
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aReportType The type of report (input/output/feature) requested
     * @param aReportID The specific report required
     * @param aInterface The interface we want the report from
     * @param aLength The expected length of the report buffer
     * @return None.
     */
    virtual void GetReportL(TInt aConnID, TUint8 aReportType,TUint8 aReportID,
        TUint16 aInterface, TUint16 aLength) = 0;

    /**
     * Request to send a report to a device. The response will be reported via the
     * CHidTransport::CommandResult function
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aReportType The type of report (input/output/feature) requested
     * @param aReportID The specific report required to set
     * @param aInterface The interface we want to send the report to
     * @param aReport The report payload to be sent to the device
     * @return None.
     */
    virtual void SetReportL(TInt aConnID, TUint8 aReportType,TUint8 aReportID,
        TUint16 aInterface, const TDesC8& aReport) = 0;

    /**
     * Request to send data to a device. There are no responses to this report from device.
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aReportID The specific report required
     * @param aInterface The interface we want to send the report to
     * @param aReport The report payload to be sent to the device
     * @return None.
     */
    virtual void DataOutL(TInt aConnID, TUint8 aReportID,
        TUint16 aInterface, const TDesC8& aReport) = 0;

    /**
     * Request for the current idle rate of a report from the device. The response
     * will be recevied via the CHidTransport::DataIn function
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aReportID The specific report to be queried
     * @param aInterface The interface we want to query for idle rate
     * @return None.
     */
    virtual void GetIdleL(TInt aConnID, TUint8 aReportID,
        TUint16 aInterface) = 0;

    /**
     * Request to set the current idle rate for a report on the device.
     * The response will be received via the CHidTransport::CommandResult function
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @param aReportID The specific report to be queried
     * @param aDuration The time period between idle reports (4ms per bit. An
     *        interval of 0 disables idle reports so that Interrupt reports are only ever
     *        received when the reported data has changed
     * @param aReportID The specific report to be queried
     * @param aInterface The interface we want to query for idle rate
     * @return None.
     */
    virtual void SetIdleL(TInt aConnID,  TUint8 aDuration, TUint8 aReportID,
        TUint16 aInterface) = 0;
    };

/**
 *
 *  Driver access interface
 *  Interface allowing drivers to request data from and send data to devices via
 *  the Generic HID layer.
 *
 *  @since S60 v5.0
 */
class MDriverAccess
    {
public:

    /**
     * The type of report requested from the device
     * Note: The enumeration values map directly to the HID equivalent values
     * (Passed as TUint16 values to the transport layer)
     */
    enum TReportType
        {
        EInput=1,     /*!< Input report */
        EOutput,      /*!< Output report */
        EFeature      /*!< Feature report */
        };

    /** Return codes from the Generic HID to the device drivers
     * Note: The enumeration values map directly to the HID equivalent values
     *(Passed as TUint8 values to the transport layer)
     */

    enum TProtocols
        {
        EBoot=0,        /*!< Boot Protocol */
        EReport=1       /*!< Report Protocol */
        };

public:

    /**
     * Retrieves the country code for the HID device
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return contry code
     */
    virtual TUint CountryCodeL(TInt aConnID) = 0;

    /**
     * Retrieves the  for the HID device
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return vendor id
     */
    virtual TUint VendorIdL(TInt aConnID) = 0;

    /**
     * Retrieves the product identifier for the HID device
     *
     * @since S60 v5.0
     * @param aConnID The device identifier
     * @return produrct id
     */
    virtual TUint ProductIdL(TInt aConnID) = 0;

    /**
     * Requests the current protocol for the device (boot or report)
     * Leaves whit KErrInUse The request was not successful because the transport 
     * layer is busy with previous request and KErrNotReady The request failed 
     * because the device is currently unavaila
     *
     * @since S60 v5.0
     * @param aConnectionID The connection id
     * @param aInterface The current interface being used by the driver
     * @return None.
     */
    virtual void GetProtocolL(TInt aConnectionID,
        TUint16 aInterface) = 0;

    /**
     * Requests a report from the device
     * Leaves whit KErrInUse The request was not successful because the transport 
     * layer is busy with previous request and KErrNotReady The request failed 
     * because the device is currently unavailable
     *
     * @since S60 v5.0
     * @param aConnectionId The connection id
     * @param aReportId The report required from the device
     * @param aInterface The current interface being used by the driver
     * @param aLength ** NOT USED **
     * @return None
     */
    virtual void GetReportL(TInt aConnectionId, TUint8 aReportId,
        TUint16 aInterface, TUint16 aLength) = 0;

    /**
     * Requests the current Idle setting for the device
     * Leaves whit KErrInUse The request was not successful because the transport 
     * layer is busy with previous request and KErrNotReady The request failed 
     * because the device is currently unavailable
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @param aReportId The report required from the device
     * @param aInterface The current interface being used by the driver
     * @return None.
     */
    virtual void GetIdleL(TInt aConnectionId, TUint8 aReportId,
        TUint16 aInterface ) = 0;

    /**
     * Sets the protocol to be used for reports
     * Leaves whit KErrInUse The request was not successful because the transport 
     * layer is busy with previous request and KErrNotReady The request failed 
     * because the device is currently unavailable
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @param aInterface The current interface being used by the driver
     * @param aProtocol The required protocol (boot or report)
     * @parem aDriver Calling driver
     * @return None.
     */
    virtual void SetProtocolL(TInt aConnectionId,
        TUint16 aInterface, TProtocols aProtocol, CHidDriver* aDriver) = 0;

    /**
     * Sets the idle interval for interrupt data.
     * Leaves whit KErrInUse The request was not successful because the transport 
     * layer is busy with previous request and KErrNotReady The request failed 
     * because the device is currently unavailable
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @param aDuration The idle interval, in steps of 0.04ms intervals (where
     *                  1 = 0.04ms, 2=0.08ms). 0 will disable idle so reports
     *                   are only sent when the state of the device changes
     * @param aInterface The current interface being used by the driver
     * @param aReportId The report whose idle rate is being set
     * @param aInterface The current interface being used by the driver
     * @parem aDriver Calling driver
     * @return None.
     */
    virtual void SetIdleL(TInt aConnectionId, TUint8 aDuration,
        TUint8 aReportId, TUint16 aInterface, CHidDriver* aDriver) = 0;


    /**
     * Sends a report to the device
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @param aReportId The report to receive the setup report
     * @param aReportType The type of report being sent to the device (input, output
     *                     or Feature)
     * @param aPayload The report being sent to the device
     * @parem aDriver Calling driver
     * @param aInterface The current interface being used by the driver
     * @return KErrNone The request was successful and the result of the command is
     *         expected at a later time (as a CmdAck message), KErrInUse The request
     *         was not successful because the transport layer is busy with a previous
     *         request, KErrNotReady The request failed because the device is currently
     *         unavailable and KErrNoMemory The request failed because not enough memory
     *         available
     */
    virtual void SetReportL(TInt aConnectionId, TUint8 aReportId,
        TReportType aReportType, const TDesC8& aPayload,
        TUint16 aInterface, CHidDriver* aDriver) = 0;

    /**
     * Sends a report to the device (from host) using Interrupt Channel as DATA
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @param aReportId The report to receive the setup report
     * @param aPayload The report being sent to the device
     * @param aInterface The current interface being used by the driver
     * @return KErrNone The request was successful and the result of the
     *         command is expected at a later time (as a CmdAck message),
     *         KErrInUse The request was not successful because the transport layer is
     *         busy with a previous request, KErrNotReady The request failed because the
     *         device is currently unavailable and KErrNoMemory The request failed because
     *         not enough memory available
     */
    virtual void DataOutL(TInt aConnectionId, TUint8 aReportId,
        /*TReportType aReportType,*/ const TDesC8& aPayload,
        TUint16 aInterface) = 0;

    /**
     * A request for the parsed descriptor container object so the driver can
     * retrieve the report format(s)
     *
     * @since S60 v5.0
     * @param aConnectionId The device ID
     * @return A pointer to the parsed report descriptor container and
     *        NULL if no parsed report descriptor container exists
     */
    virtual CReportRoot* ReportDescriptor(TInt aConnectionId) = 0;
    };


/**
 *
 *  Hid transport interface
 *  Interface allowing the transport layer to pass data to the Generic HID
 *
 *  @since S60 v5.0
 */
class CHidTransport : public CBase
    {
public:
    /**
     * Defines the channel type for the DataIn function
     */
    enum THidChannelType
        {
        EHidChannelInt,     /*!< Interrupt channel */
        EHidChannelCtrl     /*!< Control channel */
        };

    /**
     *Driver state (active or suspended)
     */
    enum TDriverState
        {
        EActive,            /*!< Driver will handle interrupt data */
        ESuspend            /*!< the driver will not handle interrupt data */
        };

public:

    /**
     * Called when a device has connected
     *
     * @since S60 v5.0
     * @param aConnectionId The transport-layer enumeration for the connection
     * @param aDescriptor The report descriptor for the device
     * @return KErrNone The connection will be handled by one or more drivers,
     *         KErrHidNoDriver No driver was found to handle the connected device
     */
    virtual TInt ConnectedL(TInt aConnectionId, const TDesC8& aDescriptor) = 0;

    /**
     * Called when a device has been disconnected
     *
     * @since S60 v5.0
     * @param aConnectionId The transport-layer enumeration for the connection
     * @param aDescriptor The report descriptor for the device
     * @return KErrNone The device was recognised and its drivers were unloaded and
     *         KErrHidNoDriver No driver was found to handle the connected device
     */
    virtual TInt Disconnected(TInt aConnectionId) = 0;

    /**
     * Called when a device has been disconnected
     *
     * @since S60 v5.0
     * @param aConnectionId Transport layer connection enumeration
     * @param aChannel Channel ID (Interrupt or Control)
     * @param aPayload The complete report payload
     * @return KErrNone The payload was handled by one or more drivers,
     *         KErrHidNoDriver No driver is handling reports from the device
     *         and KErrHidSuspended The report was not handled because all the drivers
     *         handling the device are suspended
     */
    virtual TInt DataIn(TInt aConnectionId,
        THidChannelType aChannel, const TDesC8& aPayload) = 0;

    /**
     * Suspends or Resumes the driver(s) handling the connection
     *
     * @since S60 v5.0
     * @param aConnectionId Transport layer connection enumeration
     * @param aActive The requested state of the driver (active or suspended)
     * @return KErrNone The driver was successfully put into the requested state,
     *         and KErrHidAlreadyInState All the drivers were already in the
     *         requested state
     */
    virtual TInt DriverActive(TInt aConnectionId,
        CHidTransport::TDriverState aActive) = 0;

    /**
     * Called by the transport layers to inform the generic HID of the
     * success of the last Set... command.
     *
     * @since S60 v5.0
     * @param aConnectionId Transport layer connection enumeration
     * @param  aCmdAck Status of the last Set... command
     * @return None.
     */
    virtual void CommandResult(TInt aConnectionId, TInt aCmdAck) = 0;
    };

/**
 *
 *  Driver plugin interface
 *  Interface allowing drivers to request data from and send data to devices via
 *  the Generic HID layer.
 *
 *  @lib generichid.lib 
 *  @since S60 v5.0
 */
class CHidDriver : public CBase
    {
public:


    /**
     * Two-phased constructor.
     * @param aImplementationUid Implementation UID of the plugin to be
     *                           created.
     * @param aHid               Driver acces interface
     */
    IMPORT_C static CHidDriver* NewL(
	    const TUid aImplementationUid,
    	MDriverAccess* aHid );

    /**
     * Destructor
     */
     IMPORT_C virtual ~CHidDriver();

    /**
     * Called by the Generic HID to see if the factory can use reports described by
     * the parsed report descriptor
     * NOTE: The current implementation supports just one driver and that driver
     * that will either handle all the reports from the device or none at all.
     * Report ID is not currently being taken into account.
     *
     * @since S60 v5.0
     * @param aReportDescriptor Parsed HID report descriptor
     * @return KErrNone The driver will handle reports from the report descriptor and
     *         KErrHidUnrecognised The driver cannot handle reports from the device
     */
    virtual TInt CanHandleReportL(CReportRoot* aReportDescriptor) = 0;

    /**
     * Called by the Generic HID layer when a device has sent a report on the
     * interrupt or control channel
     *
     * @since S60 v5.0
     * @param aChannel Channel ID (Interrupt or Control)
     * @param aPayload The complete report payload
     * @return Error if data can't be handled.
     */
    virtual TInt DataIn(CHidTransport::THidChannelType aChannel,
        const TDesC8& aPayload) = 0;

    /**
     * Called by the Generic HID layer when the handled device has been disconnected
     * interrupt or control channel
     *
     * @since S60 v5.0
     * @param aReason Disconnection code
     * @return None.
     */
    virtual void Disconnected(TInt aReason) = 0;

    /**
     * Called after a driver is sucessfully created by the Generic HID,
     * when a device is connected.
     *
     * @since S60 v5.0
     * @param aConnectionId An number used to identify the device in
     * subsequent calls from the driver to the generic HID, for example
     * when sending data to the device.
     * @return None.
     */
    virtual void InitialiseL(TInt aConnectionId) = 0;

    /**
     * Enables the driver so that it will configure the device and
     * start handling interrupt reports from the device
     *
     * @since S60 v5.0
     * @param aConnectionId A number used to identify the device in
     * subsequent calls from the driver to the Generic HID, for example
     * when sending data to the device.
     * @return None.
     */
    virtual void StartL(TInt aConnectionId) = 0;

    /**
     * Disables the driver so that it will stop handling device
     * interrupt reports
     *
     * @since S60 v5.0
     * @return None.
     */
    virtual void Stop() = 0;

    /**
     * Called by the transport layers to inform the generic HID of
     * the success of the last Set... command.
     *
     * @since S60 v5.0
     * @param  aCmdAck Status of the last Set... command
     * @return None.
     */
    virtual void CommandResult(TInt aCmdAck) = 0;
    
    /**
     * Return count of supported fields
     *
     * @since S60 v5.0     
     * @return Number of supported fields.
     */
    virtual TInt SupportedFieldCount()= 0;
    
    
    /**
     * Set input handling registy 
     *
     * @since S60 v5.0     
     * @param aHandlingReg  a Input handling registry
     * @return Number of supported fields.
     */
    virtual void SetInputHandlingReg(CHidInputDataHandlingReg* aHandlingReg) = 0;

    protected:
    /**
     * C++ constructor.
     */
    IMPORT_C CHidDriver();

    private: // Data

    /**
     * ECOM plugin instance UID.
     */
    TUid iDtor_ID_Key;
    };
    
#endif