/*! \file
 * \brief Implementation of Neonode's ASN.1 based protocol.
 *
 * \copyright
 * COPYRIGHT NOTICE: (c) 2017-2022 Neonode Technologies AB. All rights reserved.
 */

#ifndef PROTOCOL_ASN1PROTOCOL_ASN1PROTOCOL_H
#define PROTOCOL_ASN1PROTOCOL_ASN1PROTOCOL_H 1

#ifndef ZFORCECOMMON_H
    #error Please include "zForceCommon.h" before this file.
#endif // ZFORCECOMMON_H

//! \sa Asn1InitializationStatus
typedef enum Asn1InitializationStatus Asn1InitializationStatus;
//! Enum describing if initialization messages has been sent and received.
enum Asn1InitializationStatus
{
    Asn1Uninitialized = 0, //!< Initialization sequence not completed.
    Asn1Initialized        //!< Initialization sequence completed.
};

//! \sa Asn1Protocol
typedef struct Asn1Protocol Asn1Protocol;
/*!
 * \brief This structure represents the ASN.1 protocol class.
 */
struct Asn1Protocol
{
    /*!
     * The immediate base class of this Protocol class.
     * \n\n
     * Inherited from Protocol base class.
     */
    Protocol      * Base;

    /*! Each Protocol is linked to one connection.
     *  \n\n
     *  Inherited from Protocol base class.
     */
    Connection    * Connection;

    /*! A counter used for giving responses a unique serial number.
     *  Serial numbers start at 1 and strictly increase with each response.
     *  \n\n
     *  Inherited from Protocol base class.
     */
    uint64_t        ResponseSerialNumber;

    /*! A counter used for giving notifications a unique serial number.
     * Serial numbers start at 1 and strictly increase with each notification.
     * \n\n
     * Inherited from Protocol base class.
     */
    uint64_t        NotificationSerialNumber;

    /*! The destructor for this class.
     * \n\n
     * Inherited from Protocol base class.
     */
    void        ( * Destructor) (Protocol * self);

    /*! Protocol Specific method to destroy any potential Protocol Specific Data stored in a Device;
     * \n\n
     * Inherited from Protocol base class.
     */
    void        ( * DestroyPrivateDeviceData) (Protocol * self, void * privateDeviceData);

    /*! A pointer to the global zForce instance.
     * \n\n
     * Inherited from Protocol base class.
     */
    zForce        * zForce;

    /*!
     * \brief Perform protocol specific processing upon connection.
     *
     * Perform protocol specific processing upon connection.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set. Errno values can differ between protocols.
     *
     * \param self Pointer to the struct itself.
     *
     * \return true upon success. On failure, inspect errno for the error code.
     */
    bool        ( * Connect) (Protocol * self);

    /*!
     * \brief Perform protocol specific processing upon disconnection.
     *
     * Perform protocol specific processing upon disconnection.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set. Errno values can differ between protocols.
     *
     * \param self Pointer to the struct itself.
     *
     * \return true upon success. On failure, inspect errno for the error code.
     */
    bool        ( * Disconnect) (Protocol * self);

    /*!
     * \brief Give a data frame to Protocol for processing.
     *
     * Give a data frame to Protocol for processing.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set. Errno values can differ between protocols.
     *
     * \param self Pointer to the struct itself.
     * \param dataFrame DataFrame pointer.
     *
     * \return true if the data frame has been decoded. On failure, inspect errno for the error code.
     */
    bool        ( * DecodeDataFrame) (Protocol * self, DataFrame * dataFrame);
#if 0
    // When this is implemented, or a placeholder is placed, it will be an ABI-breaking change, but only
    // for programs implementing their own protocol.
    // So maybe better that, when we actually do other ABI-breaking changes, we implement this,
    // even if it always returns an error, as opposed to not existing.
    /*!
     * \brief Create a DeviceCount request.
     *
     * Create a DeviceCount request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateDeviceCountRequest) (Protocol * self, Device * device, MessageAction action,
                                                            uint32_t totalNumberOfDevices, bool HasTotalNumberOfDevices,
                                                            uint32_t coreDevices, bool HasCoreDevices,
                                                            uint32_t airDevices, bool HasAirDevices,
                                                            uint32_t plusDevices, bool HasPlusDevices,
                                                            uint32_t lightingDevices, bool HasLightingDevices);
#endif // 0
    /*!
     * \brief Create a Resolution request.
     *
     * Create a Resolution request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param x X axis value if this is a set action.
     * \param hasX X axis value present flag if this is a set action.
     * \param y Y axis value if this is a set action.
     * \param hasY Y axis value present flag if this is a set action.
     * \param z Z axis value if this is a set action.
     * \param hasZ Z axis value present flag if this is a set action.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateResolutionRequest) (Protocol * self, Device * device, MessageAction action,
                                                               uint32_t x, bool hasX,
                                                               uint32_t y, bool hasY,
                                                               uint32_t z, bool hasZ);

    /*!
     * \brief Create a TouchActiveArea request.
     *
     * Create a TouchActiveArea request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param lowerBoundX X axis value of lower bound.
     * \param lowerBoundY Y axis value of lower bound.
     * \param upperBoundX X axis value of upper bound.
     * \param upperBoundY Y axis value of upper bound.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateTouchActiveAreaRequest) (Protocol * self, Device * device, MessageAction action,
                                                             uint32_t lowerBoundX, uint32_t upperBoundX, bool xIsValid,
                                                             uint32_t lowerBoundY, uint32_t upperBoundY, bool yIsValid);

    /*!
     * \brief Create a ReverseTouchActiveArea request.
     *
     * Create a ReverseTouchActiveArea request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param reverseX X axis direction reversal flag.
     * \param reverseY Y axis direction reversal flag.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateReverseTouchActiveAreaRequest) (Protocol * self, Device * device, MessageAction action,
                                                                           bool xIsReversed, bool yIsReversed);

    /*!
     * \brief Create a FlipXY request.
     *
     * Create a FlipXY request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param flip the X and Y axes.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateFlipXYRequest) (Protocol * self, Device * device, MessageAction action, bool axesAreFlipped);

    /*!
     * \brief Create a ReflectiveEdgeFilter request.
     *
     * Create a ReflectiveEdgeFilter request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param isFilterOn true if the filter is on, otherwise false.
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateReflectiveEdgeFilterRequest) (Protocol * self, Device * device, MessageAction action,
                                                                         bool isFilterOn);

    /*!
     * \brief Create a MergeTouches request.
     *
     * Create a MergeTouches request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param areTouchesMerged true if the reported touches are merged, otherwise false.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateMergeTouchesRequest) (Protocol * self, Device * device, MessageAction action,
                                                                 bool areTouchesMerged);

    /*!
     * \brief Create a DetectionMode request.
     *
     * Create a DetectionMode request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateDetectionModeRequest) (Protocol * self, Device * device, MessageAction action);

    /*!
     * \brief Create a McuUniqueIdentifier request.
     *
     * Create a McuUniqueIdentifier request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param identifier Pointer to the Identifier array to set.
     * \param bufferSize Buffer size.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateMcuUniqueIdentifierRequest) (Protocol * self, Device * device, MessageAction action,
                                                                        uint8_t * identifier, uint32_t bufferSize);

    /*!
     * \brief Create an Enable request.
     *
     * Create an Enable request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param continuousMode Set to true for continuous mode.
     * \param numberOfMessages When in non-continuous mode, specifies how many Messages to receive before the Device
     *                         disables itself. May not be 0 when continuousMode == false.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateEnableRequest) (Protocol * self, Device * device, MessageAction action,
                                                           bool continuousMode, uint32_t numberOfMessages);

    /*!
     * \brief Create an OperationModes request.
     *
     * Create an OperationModes request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param modeMask Indication of which modes have values in this call.
     * \param modeValues Optional values for modes. See the modeMask argument.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateOperationModesRequest) (Protocol * self,
                                                  Device * device,
                                                  MessageAction action,
                                                  OperationModes modeMask,
                                                  OperationModes modeValues);

    /*!
     * \brief Create a Disable request.
     *
     * Create a Disable request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateDisableRequest) (Protocol * self, Device * device, MessageAction action);

    /*!
     * \brief Create a FingerFrequency request.
     *
     * Create a FingerFrequency request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param frequency The value to set if this is a set action.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateFingerFrequencyRequest) (Protocol * self, Device * device, MessageAction action,
                                                                    uint32_t frequency);

    /*!
     * \brief Create an IdleFrequency request.
     *
     * Create an IdleFrequency request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param frequency The value to set if this is a set action.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateIdleFrequencyRequest) (Protocol * self, Device * device, MessageAction action,
                                                                  uint32_t frequency);

    /*!
     * \brief Create a DetectedObjectSizeRestriction request.
     *
     * Create a DetectedObjectSizeRestriction request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param maximumSizeEnabled Maximum size enabling flag.
     * \param maximumSize The maximum object size for detection.
     * \param minimumSizeEnabled Minimum size enabling flag.
     * \param minimumSize The minimum object size for detection.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateDetectedObjectSizeRestrictionRequest) (Protocol * self, Device * device, MessageAction action,
                                                                         bool maximumSizeEnabled, uint32_t maximumSize,
                                                                         bool minimumSizeEnabled, uint32_t minimumSize);

    /*!
     * \brief Create a NumberOfTrackedObjects request.
     *
     * Create a NumberOfTrackedObjects request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param numberOfTrackedObjects Tracked object count.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateNumberOfTrackedObjectsRequest) (Protocol * self, Device * device, MessageAction action,
                                                                           uint32_t numberOfTrackedObjects);

    /*!
     * \brief Create an Offset request.
     *
     * Create an Offset request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param offsetX The X Offset.
     * \param offsetXIsValid The X Offset is valid, i.e. you want to set it.
     * \param offsetY The Y Offset.
     * \param offsetYIsValid The Y Offset is valid, i.e. you want to set it.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateOffsetRequest) (Protocol * self, Device * device, MessageAction action,
                                                           uint32_t offsetX, bool offsetXIsValid,
                                                           uint32_t offsetY, bool offsetYIsValid);

    /*!
     * \brief Create a HidDisplaySize request.
     *
     * Create a HidDisplaySize request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param sizeX The X Size.
     * \param sizeXIsValid The X Size is valid, i.e. you want to set it.
     * \param sizeY The Y Size.
     * \param sizeYIsValid The Y Size is valid, i.e. you want to set it.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateHidDisplaySizeRequest) (Protocol * self, Device * device, MessageAction action,
                                                                   uint32_t sizeX, bool sizeXIsValid,
                                                                   uint32_t sizeY, bool sizeYIsValid);

    /*!
     * \brief Create a TouchMode request.
     *
     * Create a TouchMode request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param touchMode Which Touch Mode the device is in.
     * \param clickOnTouchTime The Click on Touch Time.
     * \param clickOnTouchTimeIsValid The Click On Touch Time is valid, i.e. you want to set it.
     * \param clickOnTouchRadius The Click On Touch Radius.
     * \param clickOnTouchRadiusIsValid The Click on Touch Radius is valid, i.e. you want to set it.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateTouchModeRequest) (Protocol * self, Device * device, MessageAction action,
                                                           TouchModes touchMode, bool touchModeIsValid,
                                                           uint32_t clickOnTouchTime, bool clickOnTouchTimeIsValid,
                                                           uint32_t clickOnTouchRadius, bool clickOnTouchRadiusIsValid);

    /*!
     * \brief Create a FloatingProtection request.
     *
     * Create a FloatingProtection request.
     * \n\n
     * Inherited from Protocol base class.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param enabled Enable or disable Floating Protection.
     * \param enabledIsValid Enable is valid, i.e. you want to set it.
     * \param time Floating Protection Time in ms..
     * \param timeIsValid The Time is valid, i.e. you want to set it.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateFloatingProtectionRequest) (Protocol * self, Device * device, MessageAction action,
                                                                       bool enabled, bool enabledIsValid,
                                                                       uint32_t time, bool timeIsValid);

    /*!
     * \brief Create a Snapping Filter request.
     *
     * Create a FloatingProtection request.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param enabled Snapping Filter is enabled.
     * \param enabledIsValid Enable is valid, i.e. you want to Enable/Disable Snapping Filter.
     * \param leftInner Distance from edge to the inner snapping edge, left side of Touch Active Area.
     * \param leftOuter Distance from edge to the outer snapping edge, left side of Touch Active Area.
     * \param leftIsValid Left is valid, i.e. you want to update leftInner & leftOuter in Snapping Filter.
     * \param rightInner Distance from edge to the inner snapping edge, right side of Touch Active Area.
     * \param rightOuter Distance from edge to the outer snapping edge, right side of Touch Active Area.
     * \param rightIsValid Right is valid, i.e. you want to update rightInner & rightOuter in Snapping Filter.
     * \param topInner Distance from edge to the inner snapping edge, top side of Touch Active Area.
     * \param topOuter Distance from edge to the outer snapping edge, top side of Touch Active Area.
     * \param topIsValid Top is valid, i.e. you want to update topInner & topOuter in Snapping Filter.
     * \param bottomInner Distance from edge to the inner snapping edge, bottom side of Touch Active Area. 
     * \param bottomOuter Distance from edge to the outer snapping edge, bottom side of Touch Active Area.
     * \param bottomIsValid Bottom is valid, i.e. you want to update bottomInner & bottomOuter in Snapping Filter.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateSnappingFilterRequest) (Protocol * self, Device * device, MessageAction action,
                                                                   bool enabled, bool enabledIsValid,
                                                                   uint32_t leftInner,
                                                                   uint32_t leftOuter, bool leftIsValid,
                                                                   uint32_t rightInner,
                                                                   uint32_t rightOuter, bool rightIsValid,
                                                                   uint32_t topInner,
                                                                   uint32_t topOuter, bool topIsValid,
                                                                   uint32_t bottomInner,
                                                                   uint32_t bottomOuter, bool bottomIsValid);

    /*!
     * \brief Create a DoubleClickPrevention request.
     *
     * Create a DoubleClickPrevention request.
     * \n\n
     * On error, errno is set.
     * - ::ENOTSUPPORTED - Operation not supported.
     * - ::EPROTOCOLERROR - Generic protocol error.
     * - ::EOUTOFMEMORY - Could not dynamically allocate memory.
     *
     * \param self Pointer to the struct itself.
     * \param device Pointer to the Device from which the request originated.
     * \param action Indication of what type of action this message refers to.
     * \param enabled Enable or disable Double-Click Prevention.
     * \param enabledIsValid Enable is valid, i.e. you want to set it.
     * \param doubleClickPreventionTime Double-Click Prevention Time in ms.
     * \param doubleClickPreventionTimeIsValid Double-Click Prevention Time is valid, i.e. you want to set
     *                                         Double-Click Prevention Time.
     * \param doubleClickPreventionRadius Double-Click Prevention Radius in 1/10th of mm.
     * \param doubleClickPreventionTimeIsValid Double-Click Prevention Radius is valid, i.e. you want to set
     *                                         Double-Click Prevention Radius.
     *
     * \return Pointer to data frame if it it worked, NULL if it didn't. See errno.
     */
    DataFrame * ( * CreateDoubleClickPreventionRequest) (Protocol * self, Device * device, 
                                                                      MessageAction action,
                                                                      bool enabled, 
                                                                      bool enabledIsValid,
                                                                      uint32_t doubleClickPreventionTime,
                                                                      bool doubleClickPreventionTimeIsValid,
                                                                      uint32_t doubleClickPreventionRadius,
                                                                      bool doubleClickPreventionRadiusIsValid);

    Asn1InitializationStatus InitializationStatus; //!< Initialization status.
    void                   * Private;              //!< Private members.
};

// Exported Functions (prefixed with module name and underscore)

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

/*!
 * \brief Adds the ASN.1 Protocol to the ProtocolTable.
 *
 * On error, errno is set.
 * - ::EALREADYADDED - The ASN.1 protocol has already been added.
 * - ::EOUTOFMEMORY - The memory used to store protocol details has been exhausted.
 * - ::EMUTEXLOCKFAILED - We couldn't lock a mutex we need for an internal critical section. This should not happen.
 * - ::EBADMUTEX - We tried to use a mutex internally but it wasn't a valid mutex. This should not happen.
 * - ::EALREADYINITIALIZED - Protocol already initialized.
 *
 * \return True upon success, otherwise return false in which case see errno.
 */
DLLINTERNAL bool Asn1Protocol_Initialize (void);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // PROTOCOL_ASN1PROTOCOL_ASN1PROTOCOL_H
