summaryrefslogtreecommitdiff
path: root/hw/usb/hid-logitech-dj.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb/hid-logitech-dj.c')
-rw-r--r--hw/usb/hid-logitech-dj.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c
index a035bc533d..caa0383bc9 100644
--- a/hw/usb/hid-logitech-dj.c
+++ b/hw/usb/hid-logitech-dj.c
@@ -379,14 +379,56 @@ static void hidpp_process_device_hidpp10(USBLtunifyState *s, HidppMsg *msg)
}
}
+
+/* HID++ 2.0 */
+static void hidpp20_queue_error(USBLtunifyState *s, Hidpp20Msg *func, uint8_t err)
+{
+ Hidpp20Msg error_report = {
+ .report_id = func->report_id,
+ .device_index = func->device_index,
+ .feat_index = 0xFF,
+ .func = func->func,
+ .params = { err }
+ };
+
+ hidpp_queue_output_report(s, (HidppMsg *) &error_report);
+}
+
+/* called for HID++ 2.0 reports targeted at devices */
+static void hidpp_process_device_hidpp20(USBLtunifyState *s, HidppMsg *msg)
+{
+ LHidDevice *hd = &s->devices[msg->device_index - 1];
+ Hidpp20Msg *func = (Hidpp20Msg *) msg;
+ uint8_t fn = func->func >> 4;
+
+ if (func->feat_index == 0) { /* IRoot */
+ if (fn == 1) { /* GetProtocolVersion */
+ func->params_s[0] = (uint8_t) (hd->info.protocol_version >> 8);
+ func->params_s[1] = (uint8_t) hd->info.protocol_version;
+ hidpp_queue_output_report(s, msg);
+ } else {
+ hidpp20_queue_error(s, func, HIDPP20_ERR_CODE_INVALID_FUNCTION_ID);
+ }
+ return;
+ }
+ /* TODO: implement features and more functions */
+}
+
+
static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg)
{
/* receiver reports are processed earlier, elsewhere */
assert(msg.device_index != 0xFF);
if (hidpp_device_available(s, msg.device_index)) {
+ LHidDevice *hd = &s->devices[msg.device_index - 1];
+
if (msg.report_id == HIDPP_SHORT || msg.report_id == HIDPP_LONG) {
- hidpp_process_device_hidpp10(s, &msg);
+ if (hd->info.protocol_version >= 0x0200) {
+ hidpp_process_device_hidpp20(s, &msg);
+ } else {
+ hidpp_process_device_hidpp10(s, &msg);
+ }
}
} else {
hidpp_queue_error(s, &msg, HIDPP_ERR_RESOURCE_ERROR);