mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-04-04 06:11:07 -04:00
Dynamically parse report IDs
This commit is contained in:
committed by
Adam Honse
parent
d1e3240b9e
commit
fa66f9db4f
@@ -9,7 +9,9 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "hid_util.h"
|
||||
#include "HIDLampArrayController.h"
|
||||
|
||||
HIDLampArrayController::HIDLampArrayController(hid_device *dev_handle, const char *path, std::string dev_name)
|
||||
@@ -19,13 +21,78 @@ HIDLampArrayController::HIDLampArrayController(hid_device *dev_handle, const cha
|
||||
name = dev_name;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LampArrayAttributesReport |
|
||||
| Parse report IDs from descriptor |
|
||||
\*-----------------------------------------------------*/
|
||||
ids.LampArrayAttributesReportID = 0x01;
|
||||
ids.LampAttributesRequestReportID = 0x02;
|
||||
ids.LampAttributesResponseReportID = 0x03;
|
||||
ids.LampMultiUpdateReportID = 0x04;
|
||||
ids.LampArrayControlReportID = 0x06;
|
||||
unsigned char data_len = 0;
|
||||
unsigned char key = 0;
|
||||
unsigned char key_cmd = 0;
|
||||
unsigned char key_size = 0;
|
||||
unsigned int pos = 0;
|
||||
unsigned char report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
unsigned char report_id = 0;
|
||||
unsigned int size = hid_get_report_descriptor(dev, report_descriptor, sizeof(report_descriptor));
|
||||
unsigned int usage = 0;
|
||||
unsigned char usage_page = 0;
|
||||
|
||||
while(pos < size)
|
||||
{
|
||||
get_hid_item_size(report_descriptor, size, pos, &data_len, &key_size);
|
||||
|
||||
key = report_descriptor[pos];
|
||||
key_cmd = key & 0xFC;
|
||||
|
||||
switch(key_cmd)
|
||||
{
|
||||
case 0x4:
|
||||
usage_page = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
usage = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
|
||||
if(data_len == 4)
|
||||
{
|
||||
usage_page = usage >> 16;
|
||||
usage &= 0x0000FFFF;
|
||||
}
|
||||
if(usage_page == 0x59 && report_id)
|
||||
{
|
||||
switch(usage)
|
||||
{
|
||||
case 0x02:
|
||||
ids.LampArrayAttributesReportID = report_id;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
ids.LampAttributesRequestReportID = report_id;
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
ids.LampAttributesResponseReportID = report_id;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
ids.LampMultiUpdateReportID = report_id;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
ids.LampRangeUpdateReportID = report_id;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
ids.LampArrayControlReportID = report_id;
|
||||
break;
|
||||
}
|
||||
report_id = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
report_id = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
break;
|
||||
}
|
||||
pos += data_len + key_size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LampArrayAttributesReport |
|
||||
|
||||
107
Controllers/HIDLampArrayController/hid_util.h
Normal file
107
Controllers/HIDLampArrayController/hid_util.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*******************************************************
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user