diff options
author | Peter Wu <lekensteyn@gmail.com> | 2013-08-28 18:19:50 +0200 |
---|---|---|
committer | Peter Wu <lekensteyn@gmail.com> | 2013-09-02 11:45:34 +0200 |
commit | c511b7356460bf8818e0dcd85ed15cc7f765b701 (patch) | |
tree | b5a069c7e4559d0b2493270e6a0e0aadd37e8ca6 | |
parent | 0a0a7c80e7d3a9c1c7e8299a07a2b7b990f13099 (diff) | |
download | upower-c511b7356460bf8818e0dcd85ed15cc7f765b701.tar.gz |
hidpp: split request read/write functions
In preparation for reading notifications; the device index is now
also validated before using a message, this avoid matching the wrong
report.
Signed-off-by: Peter Wu <lekensteyn@gmail.com>
-rw-r--r-- | src/linux/hidpp-device.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c index e6e2ba7..03c7112 100644 --- a/src/linux/hidpp-device.c +++ b/src/linux/hidpp-device.c @@ -312,6 +312,14 @@ hidpp_discard_messages (HidppDevice *device) } } +static gboolean +hidpp_device_read_resp (HidppDevice *device, + guchar device_index, + guchar feature_index, + guchar function_index, + HidppMessage *response, + GError **error); + /** * hidpp_device_cmd: **/ @@ -321,20 +329,9 @@ hidpp_device_cmd (HidppDevice *device, HidppMessage *response, GError **error) { - gboolean ret = TRUE; gssize wrote; - HidppMessage read_msg = { 0 }; guint msg_len; - guchar error_code; HidppDevicePrivate *priv = device->priv; - GPollFD poll[] = { - { - .fd = priv->fd, - .events = G_IO_IN | G_IO_OUT | G_IO_ERR, - }, - }; - guint64 begin_time; - gint remaining_time; g_assert (request->type == HIDPP_MSG_TYPE_SHORT || request->type == HIDPP_MSG_TYPE_LONG); @@ -358,16 +355,47 @@ hidpp_device_cmd (HidppDevice *device, "Could not fully write HID++ request, wrote %" G_GSIZE_FORMAT " bytes", wrote); } - ret = FALSE; - goto out; + return FALSE; } + return hidpp_device_read_resp (device, + request->device_idx, + request->feature_idx, + request->function_idx, + response, + error); +} + +/** + * hidpp_device_read_resp: + */ +static gboolean +hidpp_device_read_resp (HidppDevice *device, + guchar device_index, + guchar feature_index, + guchar function_index, + HidppMessage *response, + GError **error) +{ + HidppDevicePrivate *priv = device->priv; + gboolean ret = TRUE; + gssize r; + GPollFD poll[] = { + { + .fd = priv->fd, + .events = G_IO_IN | G_IO_OUT | G_IO_ERR, + }, + }; + HidppMessage read_msg = { 0 }; + guint64 begin_time; + gint remaining_time; + guchar error_code; + /* read from the device */ begin_time = g_get_monotonic_time () / 1000; - remaining_time = HIDPP_DEVICE_READ_RESPONSE_TIMEOUT; for (;;) { - wrote = g_poll (poll, G_N_ELEMENTS(poll), remaining_time); - if (wrote < 0) { + r = g_poll (poll, G_N_ELEMENTS(poll), remaining_time); + if (r < 0) { if (errno == EINTR) continue; @@ -376,16 +404,16 @@ hidpp_device_cmd (HidppDevice *device, g_strerror (errno)); ret = FALSE; goto out; - } else if (wrote == 0) { + } else if (r == 0) { g_set_error (error, 1, 0, "Attempt to read response from device timed out"); ret = FALSE; goto out; } - wrote = read (priv->fd, &read_msg, sizeof (*response)); - if (wrote <= 0) { - if (wrote == -1 && errno == EINTR) + r = read (priv->fd, &read_msg, sizeof (*response)); + if (r <= 0) { + if (r == -1 && errno == EINTR) continue; g_set_error (error, 1, 0, @@ -404,15 +432,21 @@ hidpp_device_cmd (HidppDevice *device, continue; } - if (read_msg.feature_idx == request->feature_idx && - read_msg.function_idx == request->function_idx) { + /* not our device */ + if (read_msg.device_idx != device_index) { + continue; + } + + /* yep, this is our request */ + if (read_msg.feature_idx == feature_index && + read_msg.function_idx == function_index) { break; } /* recognize HID++ 1.0 errors */ if (hidpp_is_error(&read_msg, &error_code) && - read_msg.function_idx == request->feature_idx && - read_msg.s.params[0] == request->function_idx) { + read_msg.function_idx == feature_index && + read_msg.s.params[0] == function_index) { g_set_error (error, 1, 0, "Unable to satisfy request, HID++ error %02x", error_code); ret = FALSE; |