/*
* 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
/**
* @}
*/