summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/hid-logitech-dj.c37
-rw-r--r--hw/usb/hid-logitech-dj.h3
2 files changed, 39 insertions, 1 deletions
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)