From 28702c7fa5e93e5597e08014edc95b13df414936 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 19 Mar 2014 23:43:09 +0100 Subject: unifying: start implementing device report processing Signed-off-by: Peter Wu --- hw/usb/hid-logitech-dj.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index 883830a841..dc3d9c171d 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -302,14 +302,53 @@ static void hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg) } } +/* called for HID++ reports targeted at devices */ +static void hidpp_process_device_hidpp10(USBLtunifyState *s, HidppMsg *msg) +{ + LHidDevice *hd = &s->devices[msg->device_index - 1]; + HidppMsgLong *ml = &msg->hidpp_l; + unsigned req = (ml->report_id << 16) | (ml->sub_id << 8) | ml->address; + uint8_t *parms = ml->value; /* NOTE: drops address */ + + switch (req) { + case GET_REG(0x00): /* Enable HID++ notifs */ + parms[0] = (uint8_t) hd->reporting_flags; + parms[1] = 0; + parms[2] = (uint8_t) (hd->reporting_flags >> 8); + hidpp_queue_output_report(s, msg); + break; + case SET_REG(0x00): /* Enable HID++ notifs */ + hd->reporting_flags = (parms[2] << 8) | parms[0]; + hd->reporting_flags &= REPORTING_FLAG_DEV_MASK; + memset(parms, 0, 3); + hidpp_queue_output_report(s, msg); + break; + default: + /* unknown request, return error */ + switch (req & ~0xFF) { + case SET_REG(0): + case GET_REG(0): + case SET_LONG_REG(0): + case GET_LONG_REG(0): + /* register request unsatisfied */ + hidpp_queue_error(s, msg, HIDPP_ERR_INVALID_ADDRESS); + break; + default: + /* invalid report ID and command SubID combination */ + hidpp_queue_error(s, msg, HIDPP_ERR_INVALID_SUBID); + } + } +} + 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)) { - /* TODO: implement for devices */ - hidpp_queue_error(s, &msg, HIDPP_ERR_REQUEST_UNAVAILABLE); + if (msg.report_id == HIDPP_SHORT || msg.report_id == HIDPP_LONG) { + hidpp_process_device_hidpp10(s, &msg); + } } else { hidpp_queue_error(s, &msg, HIDPP_ERR_RESOURCE_ERROR); } -- cgit v1.2.1