diff options
author | Peter Wu <lekensteyn@gmail.com> | 2013-08-06 19:57:09 +0200 |
---|---|---|
committer | Peter Wu <lekensteyn@gmail.com> | 2013-08-22 22:58:16 +0200 |
commit | a375524c52e75079236127f9a89bd335cd37b3c9 (patch) | |
tree | 411e61896cb1220fea49b4d8f03b19782b10d734 | |
parent | 79643504344c1df5bdc3cfb18fd4eb75a9b6de66 (diff) | |
download | upower-a375524c52e75079236127f9a89bd335cd37b3c9.tar.gz |
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 <lekensteyn@gmail.com>
-rw-r--r-- | src/linux/hidpp-device.c | 25 |
1 files changed, 25 insertions, 0 deletions
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 <sys/stat.h> #include <sys/types.h> #include <unistd.h> +#include <errno.h> #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) { |