/*! * @file libhid.h * @brief HID Library - User API * * @author Copyright (C) 2003 * Arnaud Quette && * Charles Lepple * 2005 Peter Selinger * * This program is sponsored by MGE UPS SYSTEMS - opensource.mgeups.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * -------------------------------------------------------------------------- */ #ifndef _LIBHID_H #define _LIBHID_H #include "config.h" #include #include #include "hidtypes.h" #ifdef HAVE_STDINT_H #include /* for uint16_t */ #endif #include "timehead.h" #ifdef SHUT_MODE struct shut_dev_handle_t_s { int upsfd; /* point to main.c/upsfd */ char *device_path; }; typedef struct shut_dev_handle_t_s shut_dev_handle_t; typedef shut_dev_handle_t hid_dev_handle_t; #else #include typedef usb_dev_handle hid_dev_handle_t; #endif /* use explicit booleans */ #ifndef FALSE typedef enum ebool { FALSE, TRUE } bool_t; #else typedef int bool_t; #endif /* Device open modes */ #define MODE_OPEN 0 /* open a HID device for the first time */ #define MODE_REOPEN 1 /* reopen a HID device that was opened before */ #define MODE_NOHID 2 /* open a non-HID device; only used by libusb_open() */ #define MAX_TS 2 /* validity period of a gotten report (2 sec) */ /* ---------------------------------------------------------------------- */ /* structure to describe an item in a usage table */ typedef struct { const char *usage_name; unsigned int usage_code; } usage_lkp_t; extern usage_lkp_t hid_usage_lkp[]; /* an object of type usage_tables_t is a NULL-terminated array of * pointers to individual usage tables. */ typedef usage_lkp_t *usage_tables_t; /*! * HIDDevice_t: Describe a USB device. This structure contains exactly * the 5 pieces of information by which a USB device identifies * itself, so it serves as a kind of "fingerprint" of the device. This * information must be matched exactly when reopening a device, and * therefore must not be "improved" or updated by a client * program. Vendor, Product, and Serial can be NULL if the * corresponding string did not exist or could not be retrieved. * * (Note: technically, there is no such thing as a "HID device", but * only a "USB device", which can have zero or one or more HID and * non-HID interfaces. The HIDDevice_t structure describes a device, not * an interface, and it should really be called USBDevice). */ typedef struct { uint16_t VendorID; /*!< Device's Vendor ID */ uint16_t ProductID; /*!< Device's Product ID */ char* Vendor; /*!< Device's Vendor Name */ char* Product; /*!< Device's Product Name */ char* Serial; /* Product serial number */ char* Bus; /* Bus name, e.g. "003" */ } HIDDevice_t; /*! * HIDDeviceMatcher_t: A "USB matcher" is a callback function that * inputs a HIDDevice_t structure, and returns 1 for a match and 0 * for a non-match. Thus, a matcher provides a criterion for * selecting a USB device. The callback function further is * expected to return -1 on error with errno set, and -2 on other * errors. Matchers can be connected in a linked list via the * "next" field. This is used e.g. in libusb_open() and * HIDOpenDevice(). */ struct HIDDeviceMatcher_s { int (*match_function)(HIDDevice_t *d, void *privdata); void *privdata; struct HIDDeviceMatcher_s *next; }; typedef struct HIDDeviceMatcher_s HIDDeviceMatcher_t; /* invoke matcher against device */ static inline int matches(HIDDeviceMatcher_t *matcher, HIDDevice_t *device) { if (!matcher) { return 1; } return matcher->match_function(device, matcher->privdata); } /* constructors and destructors for specific types of matchers. An exact matcher matches a specific HIDDevice_t structure (except for the Bus component, which is ignored). A regex matcher matches devices based on a set of regular expressions. The new_* functions return a matcher on success, or NULL on error with errno set. Note that the "free_*" functions only free the current matcher, not any others that are linked via "next" fields. */ HIDDeviceMatcher_t *new_exact_matcher(HIDDevice_t *d); int new_regex_matcher(HIDDeviceMatcher_t **matcher, char *regex_array[6], int cflags); void free_exact_matcher(HIDDeviceMatcher_t *matcher); void free_regex_matcher(HIDDeviceMatcher_t *matcher); /*! * Describe a linked list of HID Events (nodes in the HID tree with * values). */ struct HIDEvent_s { char* Path; /*!< HID Object's fully qualified HID path (allocated) */ long Value; /*!< HID Object Value */ struct HIDEvent_s *next; /* linked list */ }; typedef struct HIDEvent_s HIDEvent_t; /* Describe a set of values to match for finding a special HID device. * This is given by a set of (compiled) regular expressions. If any * expression is NULL, it matches anything. The second set of values * are the original (not compiled) regular expression strings. They * are only used to product human-readable log messages, but not for * the actual matching. */ struct MatchFlags_s { regex_t *re_Vendor; regex_t *re_VendorID; regex_t *re_Product; regex_t *re_ProductID; regex_t *re_Serial; }; typedef struct MatchFlags_s MatchFlags_t; /*! * communication_subdriver_s: structure to describe the communication routines * @name: can be either "shut" for Serial HID UPS Transfer (from MGE) or "usb" */ struct communication_subdriver_s { char *name; /* name of this subdriver */ char *version; /* version of this subdriver */ int (*open)(hid_dev_handle_t **sdevp, /* try to open the next available */ HIDDevice_t *curDevice, /* device matching HIDDeviceMatcher_t */ HIDDeviceMatcher_t *matcher, unsigned char *ReportDesc, int mode); void (*close)(hid_dev_handle_t *sdev); int (*get_report)(hid_dev_handle_t *sdev, int ReportId, unsigned char *raw_buf, int ReportSize ); int (*set_report)(hid_dev_handle_t *sdev, int ReportId, unsigned char *raw_buf, int ReportSize ); int (*get_string)(hid_dev_handle_t *sdev, int StringIdx, char *string); int (*get_interrupt)(hid_dev_handle_t *sdev, unsigned char *buf, int bufsize, int timeout); }; typedef struct communication_subdriver_s communication_subdriver_t; extern communication_subdriver_t *comm_driver; /* ---------------------------------------------------------------------- */ /* * HIDOpenDevice * -------------------------------------------------------------------------- */ HIDDevice_t *HIDOpenDevice(hid_dev_handle_t **udevp, HIDDevice_t *hd, HIDDeviceMatcher_t *matcher, int mode); /* * HIDGetItemValue * -------------------------------------------------------------------------- */ int HIDGetItemValue(hid_dev_handle_t *udev, char *path, float *Value, usage_tables_t *utab); /* * HIDGetItemString * -------------------------------------------------------------------------- */ char *HIDGetItemString(hid_dev_handle_t *udev, char *path, unsigned char *rawbuf, usage_tables_t *utab); /* * HIDSetItemValue * -------------------------------------------------------------------------- */ bool_t HIDSetItemValue(hid_dev_handle_t *udev, char *path, float value, usage_tables_t *utab); /* * HIDFreeEvents * -------------------------------------------------------------------------- */ void HIDFreeEvents(HIDEvent_t *events); /* * HIDGetEvents * -------------------------------------------------------------------------- */ int HIDGetEvents(hid_dev_handle_t *udev, HIDDevice_t *dev, HIDEvent_t **eventsListp, usage_tables_t *utab); /* * HIDCloseDevice * -------------------------------------------------------------------------- */ void HIDCloseDevice(hid_dev_handle_t *udev); /* * Support functions * -------------------------------------------------------------------------- */ void HIDDumpTree(hid_dev_handle_t *udev, usage_tables_t *utab); #endif /* _LIBHID_H */