mirror of
https://github.com/Lekensteyn/ltunify.git
synced 2025-12-09 18:05:34 +00:00
ltunify: introduce read timeouts
In case a message does not get a response (user pulled out the receiver, thunder hit the device, coke has fallen on a keyboard, etc.), do not wait `for(;;)`. (2 seconds because accessing registers may be slow)
This commit is contained in:
29
ltunify.c
29
ltunify.c
@@ -29,6 +29,7 @@
|
|||||||
#include <arpa/inet.h> /* ntohs, ntohl */
|
#include <arpa/inet.h> /* ntohs, ntohl */
|
||||||
#include <glob.h> /* for /dev/hidrawX discovery */
|
#include <glob.h> /* for /dev/hidrawX discovery */
|
||||||
#include <getopt.h> /* for getopt_long */
|
#include <getopt.h> /* for getopt_long */
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#ifndef PACKAGE_VERSION
|
#ifndef PACKAGE_VERSION
|
||||||
# define PACKAGE_VERSION "0.1"
|
# define PACKAGE_VERSION "0.1"
|
||||||
@@ -295,7 +296,7 @@ static void dump_msg(struct hidpp_message *msg, size_t payload_size, const char
|
|||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t do_io(int fd, struct hidpp_message *msg, bool is_write) {
|
static ssize_t do_io(int fd, struct hidpp_message *msg, bool is_write, int timeout) {
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
size_t payload_size = SHORT_MESSAGE_LEN;
|
size_t payload_size = SHORT_MESSAGE_LEN;
|
||||||
|
|
||||||
@@ -307,6 +308,19 @@ static ssize_t do_io(int fd, struct hidpp_message *msg, bool is_write) {
|
|||||||
dump_msg(msg, payload_size, "wr");
|
dump_msg(msg, payload_size, "wr");
|
||||||
r = write(fd, msg, payload_size);
|
r = write(fd, msg, payload_size);
|
||||||
} else {
|
} else {
|
||||||
|
struct pollfd pollfd;
|
||||||
|
pollfd.fd = fd;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
|
||||||
|
r = poll(&pollfd, 1, timeout);
|
||||||
|
if (r < 0) {
|
||||||
|
perror("poll");
|
||||||
|
return 0;
|
||||||
|
} else if (r == 0) {
|
||||||
|
// timeout
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = read(fd, msg, payload_size);
|
r = read(fd, msg, payload_size);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
@@ -324,11 +338,11 @@ static ssize_t do_io(int fd, struct hidpp_message *msg, bool is_write) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static ssize_t do_read(int fd, struct hidpp_message *msg) {
|
static ssize_t do_read(int fd, struct hidpp_message *msg, int timeout) {
|
||||||
return do_io(fd, msg, false);
|
return do_io(fd, msg, false, timeout);
|
||||||
}
|
}
|
||||||
static ssize_t do_write(int fd, struct hidpp_message *msg) {
|
static ssize_t do_write(int fd, struct hidpp_message *msg) {
|
||||||
return do_io(fd, msg, true);
|
return do_io(fd, msg, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_report_id_str(u8 report_type) {
|
const char *get_report_id_str(u8 report_type) {
|
||||||
@@ -384,7 +398,7 @@ static bool do_read_skippy(int fd, struct hidpp_message *msg,
|
|||||||
u8 exp_report_id, u8 exp_sub_id) {
|
u8 exp_report_id, u8 exp_sub_id) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
msg->report_id = exp_report_id;
|
msg->report_id = exp_report_id;
|
||||||
if (!do_read(fd, msg)) {
|
if (!do_read(fd, msg, 2000)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (msg->report_id == exp_report_id && msg->sub_id == exp_sub_id) {
|
if (msg->report_id == exp_report_id && msg->sub_id == exp_sub_id) {
|
||||||
@@ -602,6 +616,9 @@ bool device_unpair(int fd, u8 device_index) {
|
|||||||
|
|
||||||
void perform_pair(int fd, u8 timeout) {
|
void perform_pair(int fd, u8 timeout) {
|
||||||
struct hidpp_message msg;
|
struct hidpp_message msg;
|
||||||
|
if (timeout == 0) {
|
||||||
|
timeout = 30;
|
||||||
|
}
|
||||||
if (!pair_start(fd, timeout)) {
|
if (!pair_start(fd, timeout)) {
|
||||||
fprintf(stderr, "Failed to send pair request\n");
|
fprintf(stderr, "Failed to send pair request\n");
|
||||||
return;
|
return;
|
||||||
@@ -610,7 +627,7 @@ void perform_pair(int fd, u8 timeout) {
|
|||||||
// WARNING: mess ahead. I knew it would become messy before writing it.
|
// WARNING: mess ahead. I knew it would become messy before writing it.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
msg.report_id = SHORT_MESSAGE;
|
msg.report_id = SHORT_MESSAGE;
|
||||||
if (!do_read(fd, &msg)) {
|
if (!do_read(fd, &msg, timeout * 1000 + 2000)) {
|
||||||
fprintf(stderr, "Failed to read short message\n");
|
fprintf(stderr, "Failed to read short message\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user