From 132f9373a5df313103a059b254906ef90cc8e8e1 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 6 Aug 2013 19:57:09 +0200 Subject: [PATCH] hidpp: clear message queue before initiating new requests (v2) This prevents the use of responses from other HID++ applications (such as Solaar and ltunify). - v2: do not hang in a loop when read() fails, e.g. when it returns EIO because the device was unplugged. Signed-off-by: Peter Wu --- src/linux/hidpp-device.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c index 6d02bf1..6943920 100644 --- a/src/linux/hidpp-device.c +++ b/src/linux/hidpp-device.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "hidpp-device.h" @@ -271,6 +272,27 @@ hidpp_device_print_buffer (HidppDevice *device, const HidppMessage *msg) g_print ("param[0]=%02x\n\n", msg->s.params[0]); } +static void +hidpp_discard_messages (HidppDevice *device) +{ + HidppDevicePrivate *priv = device->priv; + GPollFD poll[] = { + { + .fd = priv->fd, + .events = G_IO_IN | G_IO_OUT | G_IO_ERR, + }, + }; + char c; + int r; + + while (g_poll (poll, G_N_ELEMENTS(poll), 0) > 0) { + /* kernel discards remainder of packet */ + r = read (priv->fd, &c, 1); + if (r < 0 && errno != EINTR) + break; + } +} + /** * hidpp_device_cmd: **/ @@ -302,6 +324,9 @@ hidpp_device_cmd (HidppDevice *device, msg_len = HIDPP_MSG_LENGTH(request); + /* ignore all unrelated queued messages */ + hidpp_discard_messages(device); + /* write to the device */ wrote = write (priv->fd, (const char *)request, msg_len); if ((gsize) wrote != msg_len) {