From b6f142f7f999c8453a64dbe4cfa1ef5d843b56c7 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 19 Mar 2014 22:17:37 +0100 Subject: unifying: implement 0x41 notification, trigger on reg 02 Signed-off-by: Peter Wu --- hw/usb/hid-logitech-dj.c | 37 +++++++++++++++++++++++++++++++++++++ hw/usb/hid-logitech-dj.h | 3 ++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index d8bcbb06d7..6290a1bb39 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -100,6 +100,30 @@ static bool hidpp_device_available(USBLtunifyState *s, uint8_t device_index) s->devices[device_index - 1].powered_on; } +static void hidpp_notif_device_connection(USBLtunifyState *s, uint8_t device_index) +{ + HidppMsgShort msg; + LHidDevice *hd; + uint8_t devinfo = 0; + + assert(device_index >= 1 && device_index <= MAX_DEVICES); + hd = &s->devices[device_index - 1]; + msg.report_id = HIDPP_SHORT; + msg.device_index = device_index; + msg.sub_id = 0x41; /* Device Connection notif */ + msg.params[0] = hd->info.protocol_type; + /* device info */ + devinfo = hd->info.device_type & 0xF; + devinfo |= !!(hd->reporting_flags & REPORTING_FLAG_RCV_SOFTWARE_PRESENT) << 4; + devinfo |= (!!hd->link_encrypted << 5); + devinfo |= (!hd->powered_on << 6); + // bit7 = connect reason: packet with (1) or without (0) payload + msg.params[1] = devinfo; + msg.params[2] = (uint8_t) hd->info.wireless_pid; + msg.params[3] = (uint8_t) (hd->info.wireless_pid >> 8); + hidpp_queue_output_report(s, (HidppMsg *) &msg); +} + static bool hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg) { LHidDevice *hd; @@ -181,6 +205,18 @@ static bool hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg) } hidpp_queue_output_report(s, msg); break; + case SET_REG(0x02): /* Connection State? (undocumented) */ + if ((ms->value[0] & 2) && + (rcvr->reporting_flags & REPORTING_FLAG_RCV_WIRELESS_NOTIFS)) { + for (i = 0; i < MAX_DEVICES; i++) { + if (hidpp_device_available(s, i + 1)) { + hidpp_notif_device_connection(s, i + 1); + } + } + } + memset(ms->value, 0, 3); + hidpp_queue_output_report(s, msg); + break; case GET_LONG_REG(0xB3): /* Device Activity */ memset(ml->value, 0, sizeof(ml->value)); ml->report_id = HIDPP_LONG; @@ -388,6 +424,7 @@ static void hidpp_init_device(USBLtunifyState *s, int device_index, int devtype) memset(hd, 0, sizeof(*hd)); hd->info.device_type = devtype; + hd->info.protocol_type = PROTO_UNIFYING; switch (devtype) { case DEVTYPE_KEYBOARD: hd->hid = &s->hid[IFACE_KBD]; diff --git a/hw/usb/hid-logitech-dj.h b/hw/usb/hid-logitech-dj.h index fae86b8d19..04a31c95a3 100644 --- a/hw/usb/hid-logitech-dj.h +++ b/hw/usb/hid-logitech-dj.h @@ -178,7 +178,8 @@ typedef struct { LTUNIFY_MODE_HID = 1, LTUNIFY_MODE_DJ = 2 } mode; - bool powered_on; + bool powered_on; /* "link established, in range" */ + bool link_encrypted; uint8_t report_interval; #define REPORTING_FLAG_RCV_WIRELESS_NOTIFS 1 #define REPORTING_FLAG_RCV_SOFTWARE_PRESENT (1 << 3) -- cgit v1.2.1