/* * Copyright (c) 2011 Matej Klonfar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @addtogroup libusb * @{ */ /** @file * Basic data structures for USB HID Report descriptor and report parser. */ #ifndef LIBUSB_HIDTYPES_H_ #define LIBUSB_HIDTYPES_H_ #include <stdint.h> #include <adt/list.h> /** * Maximum amount of specified usages for one report item */ #define USB_HID_MAX_USAGES 0xffff /** * Converts integer from unsigned two's complement format format to signed * one. * * @param x Number to convert * @param size Length of the unsigned number in bites * @return signed int */ #define USB_HID_UINT32_TO_INT32(x, size) \ ((((x) & (1 << ((size) - 1))) != 0) ? \ -(~((x) - 1) & ((1 << size) - 1)) : (x)) /** * Convert integer from signed format to unsigned. If number is negative the * two's complement format is used. * * @param x Number to convert * @param size Length of result number in bites * @return unsigned int */ #define USB_HID_INT32_TO_UINT32(x, size) \ (((x) < 0 ) ? ((1 << (size)) + (x)) : (x)) /** * Enum of report types */ typedef enum { /** Input report. Data are sent from device to system */ USB_HID_REPORT_TYPE_INPUT = 1, /** Output report. Data are sent from system to device */ USB_HID_REPORT_TYPE_OUTPUT = 2, /** Feature report. Describes device configuration information that * can be sent to the device */ USB_HID_REPORT_TYPE_FEATURE = 3 } usb_hid_report_type_t; /** * Description of all reports described in one report descriptor. */ typedef struct { /** Count of available reports. */ int report_count; /** List of description of reports. */ list_t reports; /* of usb_hid_report_description_t */ /** List of all used usage/collection paths. */ list_t collection_paths; /** Length of list of usage paths. */ int collection_paths_count; /** Flag whether report ids are used. */ int use_report_ids; /** Report id of last parsed report. */ uint8_t last_report_id; } usb_hid_report_t; /** * Description of one concrete report */ typedef struct { /** Report id. Zero when no report id is used. */ uint8_t report_id; /** Type of report */ usb_hid_report_type_t type; /** Bit length of the report */ size_t bit_length; /** Number of items in report */ size_t item_length; /** List of report items in report */ list_t report_items; /** Link to usb_hid_report_t.reports list. */ link_t reports_link; } usb_hid_report_description_t; /** * Description of one field/item in report */ typedef struct { /** Bit offset of the field */ int offset; /** Bit size of the field */ size_t size; /** Usage page. Zero when usage page can be changed. */ uint16_t usage_page; /** Usage. Zero when usage can be changed. */ uint16_t usage; /** Item's attributes */ uint8_t item_flags; /** Usage/Collection path of the field. */ usb_hid_report_path_t *collection_path; /** * The lowest valid logical value (value with the device operates) */ int32_t logical_minimum; /** * The greatest valid logical value */ int32_t logical_maximum; /** * The lowest valid physical value (value with the system operates) */ int32_t physical_minimum; /** The greatest valid physical value */ int32_t physical_maximum; /** The lowest valid usage index */ int32_t usage_minimum; /** The greatest valid usage index */ int32_t usage_maximum; /** Unit of the value */ uint32_t unit; /** Unit exponent */ uint32_t unit_exponent; /** Array of possible usages */ uint32_t *usages; /** Size of the array of usages */ size_t usages_count; /** Parsed value */ int32_t value; /** Link to usb_hid_report_description_t.report_items list */ link_t ritems_link; } usb_hid_report_field_t; /** * State table for report descriptor parsing */ typedef struct { /** report id */ int32_t id; /** Extended usage page */ uint16_t extended_usage_page; /** Array of usages specified for this item */ uint32_t usages[USB_HID_MAX_USAGES]; /** Length of usages array */ int usages_count; /** Usage page */ uint32_t usage_page; /** Minimum valid usage index */ int32_t usage_minimum; /** Maximum valid usage index */ int32_t usage_maximum; /** Minimum valid logical value */ int32_t logical_minimum; /** Maximum valid logical value */ int32_t logical_maximum; /** Length of the items in bits */ int32_t size; /** Count of items */ int32_t count; /** Bit offset of the item in report */ size_t offset; /** Unit exponent */ int32_t unit_exponent; /** Unit of the value */ int32_t unit; /** String index */ uint32_t string_index; /** Minimum valid string index */ uint32_t string_minimum; /** Maximum valid string index */ uint32_t string_maximum; /** The designator index */ uint32_t designator_index; /** Minimum valid designator value */ uint32_t designator_minimum; /** Maximum valid designator value */ uint32_t designator_maximum; /** Minimal valid physical value */ int32_t physical_minimum; /** Maximal valid physical value */ int32_t physical_maximum; /** Items attributes */ uint8_t item_flags; /** Report type */ usb_hid_report_type_t type; /** current collection path */ usb_hid_report_path_t *usage_path; /** Unused */ link_t link; int in_delimiter; } usb_hid_report_item_t; /** * Enum of the keyboard modifiers */ typedef enum { USB_HID_MOD_LCTRL = 0x01, USB_HID_MOD_LSHIFT = 0x02, USB_HID_MOD_LALT = 0x04, USB_HID_MOD_LGUI = 0x08, USB_HID_MOD_RCTRL = 0x10, USB_HID_MOD_RSHIFT = 0x20, USB_HID_MOD_RALT = 0x40, USB_HID_MOD_RGUI = 0x80, USB_HID_MOD_COUNT = 8 } usb_hid_modifiers_t; static const usb_hid_modifiers_t usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { USB_HID_MOD_LCTRL, USB_HID_MOD_LSHIFT, USB_HID_MOD_LALT, USB_HID_MOD_LGUI, USB_HID_MOD_RCTRL, USB_HID_MOD_RSHIFT, USB_HID_MOD_RALT, USB_HID_MOD_RGUI }; #endif /** * @} */