/******************************************************* Utility functions taken from: HIDAPI - Multi-Platform library for communication with HID devices. Alan Ott Signal 11 Software libusb/hidapi Team Copyright 2022, All Rights Reserved. At the discretion of the user of this library, this software may be licensed under the terms of the GNU General Public License v3, a BSD-Style license, or the original HIDAPI license as outlined in the LICENSE.txt, LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt files located at the root of the source distribution. These files may also be found in the public source code repository located at: https://github.com/libusb/hidapi . ********************************************************/ /* * Gets the size of the HID item at the given position * Returns 1 if successful, 0 if an invalid key * Sets data_len and key_size when successful */ static int get_hid_item_size(const unsigned char *report_descriptor, unsigned size, unsigned pos, unsigned char *data_len, unsigned char *key_size) { int key = report_descriptor[pos]; int size_code; /* * This is a Long Item. The next byte contains the * length of the data section (value) for this key. * See the HID specification, version 1.11, section * 6.2.2.3, titled "Long Items." */ if ((key & 0xf0) == 0xf0) { if (pos + 1 < size) { *data_len = report_descriptor[pos + 1]; *key_size = 3; return 1; } *data_len = 0; /* malformed report */ *key_size = 0; } /* * This is a Short Item. The bottom two bits of the * key contain the size code for the data section * (value) for this key. Refer to the HID * specification, version 1.11, section 6.2.2.2, * titled "Short Items." */ size_code = key & 0x3; switch (size_code) { case 0: case 1: case 2: *data_len = size_code; *key_size = 1; return 1; case 3: *data_len = 4; *key_size = 1; return 1; default: /* Can't ever happen since size_code is & 0x3 */ *data_len = 0; *key_size = 0; break; }; /* malformed report */ return 0; } /* * Get bytes from a HID Report Descriptor. * Only call with a num_bytes of 0, 1, 2, or 4. */ static unsigned get_hid_report_bytes(unsigned char *rpt, size_t len, size_t num_bytes, size_t cur) { /* Return if there aren't enough bytes. */ if (cur + num_bytes >= len) return 0; if (num_bytes == 0) return 0; else if (num_bytes == 1) return rpt[cur + 1]; else if (num_bytes == 2) return (rpt[cur + 2] * 256 + rpt[cur + 1]); else if (num_bytes == 4) return ( rpt[cur + 4] * 0x01000000 + rpt[cur + 3] * 0x00010000 + rpt[cur + 2] * 0x00000100 + rpt[cur + 1] * 0x00000001 ); else return 0; }