summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-12-27 17:06:53 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-12-27 17:06:53 +0100
commit60283fb1407fcd1de0586c960ed8d106f59483e9 (patch)
tree306d3daa5c409b0449b4151fa8939f88ddc84884
parent4a9df9b604cec6ee4b4a6f01ef940443583f7573 (diff)
Got a clue about the pesky "SYN" messages.
I must not have read libevdev's documentation well enough. Hopefully this new approach will work better. The risk would be that the conversion takes too long and properly handling all events leads to an increasing lag between the physical and the virtual device. I should probably add an option to let users indicate they would prefer dropping missed events.
-rw-r--r--include/relabsd/device/physical_device.h36
-rw-r--r--src/device/physical/physical_device.c231
-rw-r--r--src/device/physical_device.c275
-rw-r--r--src/device/virtual/virtual_device.c (renamed from src/device/virtual_device.c)0
-rw-r--r--src/server/communication_thread.c1
-rw-r--r--src/server/conversion_main_loop.c129
-rw-r--r--src/server/interruption.c23
7 files changed, 346 insertions, 349 deletions
diff --git a/include/relabsd/device/physical_device.h b/include/relabsd/device/physical_device.h
index 17866f7..6b44802 100644
--- a/include/relabsd/device/physical_device.h
+++ b/include/relabsd/device/physical_device.h
@@ -2,10 +2,10 @@
#include <libevdev/libevdev.h>
-struct relabsd_input
+struct relabsd_physical_device
{
- struct libevdev * dev;
- int fd;
+ struct libevdev * libevdev;
+ int file;
int timed_out;
};
@@ -13,17 +13,20 @@ struct relabsd_input
* Returns -1 on (fatal) error,
* 0 on success.
*
- * 'input' does not need to be initialized, as the function will to that for
+ * 'device' does not need to be initialized, as the function will to that for
* you (on success).
* On success, 'input' will need to be closed.
*/
-int relabsd_input_open
+int relabsd_physical_device_open
(
- struct relabsd_input * const input,
- const struct relabsd_config * const conf
+ const char filename [const restrict static 1],
+ struct relabsd_physical_device device [const restrict static 1]
);
-void relabsd_input_close (const struct relabsd_input * const input);
+void relabsd_physical_device_close
+(
+ const struct relabsd_physical_device device [const restrict static 1]
+);
/*
* Returns -1 on (warning) error,
@@ -33,18 +36,15 @@ void relabsd_input_close (const struct relabsd_input * const input);
* do that for you (on success).
* Requires 'input' to be open.
*/
-int relabsd_input_read
+int relabsd_physical_device_read
(
- const struct relabsd_input * const input,
- unsigned int * const input_type,
- unsigned int * const input_code,
- int * const input_value
+ const struct relabsd_physical_device device [const restrict static 1],
+ unsigned int input_type [const restrict static 1],
+ unsigned int input_code [const restrict static 1],
+ int input_value [const restrict static 1]
);
-int relabsd_input_wait_for_next_event
+int relabsd_physical_device_is_late
(
- const struct relabsd_input * const input,
- const struct relabsd_config * const config
+ const struct relabsd_physical_device device [const restrict static 1]
);
-
-#endif
diff --git a/src/device/physical/physical_device.c b/src/device/physical/physical_device.c
new file mode 100644
index 0000000..7023791
--- /dev/null
+++ b/src/device/physical/physical_device.c
@@ -0,0 +1,231 @@
+/**** POSIX *******************************************************************/
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+/**** LIBEVDEV ****************************************************************/
+#include <libevdev/libevdev.h>
+
+/**** RELABSD *****************************************************************/
+#include <relabsd/debug.h>
+
+/******************************************************************************/
+/**** LOCAL FUNCTIONS *********************************************************/
+/******************************************************************************/
+/*
+ * Ensures that the input device has enabled the EV_REL axes mentioned
+ * in the configuration file.
+ *
+ * Returns -1 on (fatal) error,
+ * 0 all configured axes are accounted for.
+ */
+static int check_for_axes
+(
+ const struct libevdev * const dev,
+ const struct relabsd_config * const conf
+)
+{
+ int i, device_is_valid;
+ unsigned int rel_code;
+
+ device_is_valid = 1;
+
+ for (i = RELABSD_VALID_AXES_COUNT; i --> 0;)
+ {
+ if (conf->axis[i].enabled)
+ {
+ rel_code = relabsd_axis_to_rel((enum relabsd_axis) i);
+
+ if (!libevdev_has_event_code(dev, EV_REL, rel_code))
+ {
+ RELABSD_FATAL
+ (
+ "Input device has no relative %s axis, yet the configuration "
+ "file asks to convert it.",
+ relabsd_axis_to_name((enum relabsd_axis) i)
+ );
+
+ device_is_valid = 0;
+ }
+ }
+ }
+
+ return (device_is_valid - 1);
+}
+
+/*
+ * Ensures that the input device is compatible with the config file.
+ *
+ * Returns -1 on (fatal) error,
+ * 0 is the device is compatible.
+ */
+static int device_is_compatible
+(
+ const struct libevdev * const dev,
+ const struct relabsd_config * const conf
+)
+{
+
+
+ return 0;
+}
+
+/******************************************************************************/
+/**** EXPORTED FUNCTIONS ******************************************************/
+/******************************************************************************/
+int relabsd_physical_device_compatibility_test
+(
+ const struct relabsd_physical_device device [const restrict static 1],
+ const struct relabsd_parameters parameters [const restrict static 0],
+ const int verbose
+)
+{
+ if (!libevdev_has_event_type(device->libevdev, EV_REL))
+ {
+ RELABSD_S_FATAL("The physical device has no relative axes.");
+
+ return -1;
+ }
+
+ if
+ (
+ (parameters != (const struct relabsd_parameters *) NULL)
+ && (check_for_axes(device->libevdev, parameters, verbose) < 0)
+ )
+ {
+ RELABSD_S_FATAL
+ (
+ "Issue with the physical device's axes (or lack thereof), or their"
+ " compatibility with the requested configuration."
+ );
+
+ return -2;
+ }
+
+ return 0;
+}
+
+int relabsd_physical_device_open
+(
+ const char filename [const restrict static 1],
+ struct relabsd_physical_device device [const restrict static 1]
+)
+{
+ int err;
+
+ RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opening physical device...");
+
+ errno = 0;
+ device->file = open(filename, O_RDONLY);
+ device->is_late = 0;
+
+ if (device->file == -1)
+ {
+ RELABSD_FATAL
+ (
+ "Could not open physical device '%s' in read only mode: %s.",
+ filename,
+ strerror(errno)
+ );
+
+ return -1;
+ }
+
+ err = libevdev_new_from_fd(device->file, &(device->libevdev));
+
+ if (err != 0)
+ {
+ RELABSD_FATAL
+ (
+ "libevdev could not open physical device '%s': %s.",
+ filename,
+ strerror(-err)
+ );
+
+ close(device->file);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+void relabsd_physical_device_close
+(
+ const struct relabsd_physical_device device [const restrict static 1]
+)
+{
+ RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Closing input device...");
+
+ libevdev_free(device->libevdev);
+
+ errno = 0;
+
+ if (close(device->file) == -1)
+ {
+ RELABSD_ERROR
+ (
+ "Could not properly close the input device: %s.",
+ strerror(errno)
+ );
+ }
+}
+
+int relabsd_physical_device_read
+(
+ const struct relabsd_physical_device device [const restrict static 1],
+ unsigned int input_type [const restrict static 1],
+ unsigned int input_code [const restrict static 1],
+ int input_value [const restrict static 1]
+)
+{
+ int returned_code;
+ struct input_event event;
+
+ returned_code =
+ libevdev_next_event
+ (
+ device->libevdev,
+ device->is_late ? LIBEVDEV_READ_FLAG_SYNC : LIBEVDEV_READ_FLAG_NORMAL,
+ &event
+ );
+
+ switch (returned_code)
+ {
+ case LIBEVDEV_READ_STATUS_SUCCESS:
+ RELABSD_DEBUG
+ (
+ RELABSD_DEBUG_REAL_EVENTS,
+ "Valid event received: {type = %s; code = %s; value = %d}.",
+ libevdev_event_type_get_name(event.type),
+ libevdev_event_code_get_name(event.type, event.code),
+ event.value
+ );
+
+ *input_type = event.type;
+ *input_code = event.code;
+ *input_value = event.value;
+
+ return 1;
+
+ case LIBEVDEV_READ_STATUS_SYNC:
+ /* There are old events waiting to be read. */
+ device->is_late = 1;
+
+ return 0;
+
+ case -EAGAIN:
+ device->is_late = 0;
+
+ return -1;
+ }
+}
+
+int relabsd_physical_device_is_late
+(
+ const struct relabsd_physical_device device [const restrict static 1]
+)
+{
+ return device->is_late;
+}
diff --git a/src/device/physical_device.c b/src/device/physical_device.c
deleted file mode 100644
index 7e365da..0000000
--- a/src/device/physical_device.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/**** RELABSD *****************************************************************/
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-/**** LIBEVDEV ****************************************************************/
-#include <libevdev/libevdev.h>
-
-/**** RELABSD *****************************************************************/
-#include <relabsd/debug.h>
-
-/*
- * Ensures that the input device has enabled the EV_REL axes mentioned
- * in the configuration file.
- *
- * Returns -1 on (fatal) error,
- * 0 all configured axes are accounted for.
- */
-static int check_for_axes
-(
- const struct libevdev * const dev,
- const struct relabsd_config * const conf
-)
-{
- int i, device_is_valid;
- unsigned int rel_code;
-
- device_is_valid = 1;
-
- for (i = RELABSD_VALID_AXES_COUNT; i --> 0;)
- {
- if (conf->axis[i].enabled)
- {
- rel_code = relabsd_axis_to_rel((enum relabsd_axis) i);
-
- if (!libevdev_has_event_code(dev, EV_REL, rel_code))
- {
- RELABSD_FATAL
- (
- "Input device has no relative %s axis, yet the configuration "
- "file asks to convert it.",
- relabsd_axis_to_name((enum relabsd_axis) i)
- );
-
- device_is_valid = 0;
- }
- }
- }
-
- return (device_is_valid - 1);
-}
-
-/*
- * Ensures that the input device is compatible with the config file.
- *
- * Returns -1 on (fatal) error,
- * 0 is the device is compatible.
- */
-static int device_is_compatible
-(
- const struct libevdev * const dev,
- const struct relabsd_config * const conf
-)
-{
- if (!libevdev_has_event_type(dev, EV_REL))
- {
- RELABSD_S_FATAL("Input device has no relative axis.");
-
- return -1;
- }
-
- if (check_for_axes(dev, conf) < 0)
- {
- return -1;
- }
-
- return 0;
-}
-
-int relabsd_physical_device_open
-(
- struct relabsd_physical_device * const input,
- const struct relabsd_config * const conf
-)
-{
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opening input device...");
-
- input->fd = open(conf->input_file, O_RDONLY);
-
- if (input->fd < 0)
- {
- RELABSD_FATAL
- (
- "Could not open device '%s' in read only mode: %s.",
- conf->input_file,
- strerror(errno)
- );
-
- return -1;
- }
-
- if
- (
- libevdev_new_from_fd(input->fd, &(input->dev)) < 0
- )
- {
- RELABSD_FATAL
- (
- "libevdev could not open '%s': %s.",
- conf->input_file,
- strerror(errno)
- );
-
- close(input->fd);
-
- return -1;
- }
-
- if (device_is_compatible(input->dev, conf) < 0)
- {
- return -1;
- }
-
- return 0;
-}
-
-void relabsd_physical_device_close (const struct relabsd_physical_device * const input)
-{
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Closing input device...");
-
- libevdev_free(input->dev);
- close(input->fd);
-}
-
-int relabsd_physical_device_read
-(
- const struct relabsd_physical_device * const input,
- unsigned int * const input_type,
- unsigned int * const input_code,
- int * const input_value
-)
-{
- int rc;
- struct input_event event;
-
- /*
- if (libevdev_has_event_pending(input->dev) == 0)
- {
- return -1;
- }
- */
- rc =
- libevdev_next_event
- (
- input->dev,
- (LIBEVDEV_READ_FLAG_NORMAL | LIBEVDEV_READ_FLAG_BLOCKING),
- &event
- );
-
- /* TODO: Look into LIBEVDEV_READ_STATUS_SYNC, handle it. */
- /*
- if (rc == LIBEVDEV_READ_STATUS_SYNC)
- {
- handle_syn_dropped(input->dev);
- }
- else
- */
- if (rc != LIBEVDEV_READ_STATUS_SUCCESS)
- {
- RELABSD_WARNING("[INPUT] Could not get next event: %s.", strerror(-rc));
-
- return -1;
- }
-
- RELABSD_DEBUG
- (
- RELABSD_DEBUG_REAL_EVENTS,
- "Valid event received: {type = %s; code = %s; value = %d}.",
- libevdev_event_type_get_name(event.type),
- libevdev_event_code_get_name(event.type, event.code),
- event.value
- );
-
- *input_type = event.type;
- *input_code = event.code;
- *input_value = event.value;
-
- return 0;
-}
-
-int relabsd_physical_device_wait_for_next_event
-(
- const struct relabsd_physical_device * const input,
- const struct relabsd_config * const config
-)
-{
- int ready_fds;
- const int old_errno = errno;
- fd_set ready_to_read;
- struct timeval curr_timeout;
-
- FD_ZERO(&ready_to_read);
- FD_SET(input->fd, &ready_to_read);
-
- /* call to select may alter timeout */
- memcpy
- (
- (void *) &(curr_timeout),
- (const void *) &(config->timeout),
- sizeof(struct timeval)
- );
-
- errno = 0;
-
- RELABSD_S_ERROR
- (
- "Waiting for input to be ready..."
- );
-
- ready_fds = select
- (
- (input->fd + 1),
- &ready_to_read,
- (fd_set *) NULL,
- (fd_set *) NULL,
- (input->timed_out) ? NULL : &(curr_timeout)
- );
-
- if (errno != 0)
- {
- RELABSD_ERROR
- (
- "Unable to wait for timeout: %s (errno: %d).",
- strerror(errno),
- errno
- );
-
- if (errno == EINTR)
- {
- /* Signal interruption? */
- }
- else
- {
- /* TODO: error message */
- }
-
- errno = old_errno;
-
- return -1;
- }
-
- if (ready_fds == -1)
- {
- /* TODO: error message */
-
- RELABSD_S_ERROR
- (
- "Unable to wait for timeout, yet errno was not set to anything."
- );
-
- errno = old_errno;
-
- return -1;
- }
-
- RELABSD_ERROR
- (
- "Input is ready, ready_fds = %d", ready_fds
- );
-
- errno = old_errno;
-
- return ready_fds;
-}
diff --git a/src/device/virtual_device.c b/src/device/virtual/virtual_device.c
index 19d1097..19d1097 100644
--- a/src/device/virtual_device.c
+++ b/src/device/virtual/virtual_device.c
diff --git a/src/server/communication_thread.c b/src/server/communication_thread.c
index 2ed1aae..2da54d2 100644
--- a/src/server/communication_thread.c
+++ b/src/server/communication_thread.c
@@ -23,7 +23,6 @@ void * posix_main_loop (void * params)
/******************************************************************************/
/**** EXPORTED FUNCTIONS ******************************************************/
/******************************************************************************/
-
int relabsd_server_create_communication_thread
(
struct relabsd_server server [const static 1]
diff --git a/src/server/conversion_main_loop.c b/src/server/conversion_main_loop.c
index 0180e80..b5b97db 100644
--- a/src/server/conversion_main_loop.c
+++ b/src/server/conversion_main_loop.c
@@ -10,15 +10,6 @@
#include "input.h"
#include "relabsd_device.h"
-static int RELABSD_RUN = 1;
-
-static void interrupt (int unused_mandatory_parameter)
-{
- RELABSD_RUN = 0;
-
- RELABSD_S_WARNING("Interrupted, will exit at the next input device event.");
-}
-
static void handle_relative_axis_event
(
struct relabsd_config * const conf,
@@ -108,66 +99,94 @@ static void convert_input
}
}
-static int set_signal_handlers ()
+int relabsd_server_conversion_loop
+(
+ struct relabsd_server server [const static 1]
+)
{
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers.");
-
- if (signal(SIGINT, interrupt) == SIG_ERR)
- {
- RELABSD_S_FATAL("Unable to set the SIGINT signal handler.");
-
- return -1;
- }
-
return 0;
}
-/*
-int main (int argc, char ** argv)
-{
- struct relabsd_config conf;
- struct relabsd_input input;
- struct relabsd_device dev;
-
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started.");
- if (set_signal_handlers() < 0)
+int wait_for_next_event
+(
+ const struct relabsd_physical_device * const input,
+ const struct relabsd_config * const config
+)
+{
+ int ready_fds;
+ const int old_errno = errno;
+ fd_set ready_to_read;
+ struct timeval curr_timeout;
+
+ FD_ZERO(&ready_to_read);
+ FD_SET(input->fd, &ready_to_read);
+
+ /* call to select may alter timeout */
+ memcpy
+ (
+ (void *) &(curr_timeout),
+ (const void *) &(config->timeout),
+ sizeof(struct timeval)
+ );
+
+ errno = 0;
+
+ RELABSD_S_ERROR
+ (
+ "Waiting for input to be ready..."
+ );
+
+ ready_fds = select
+ (
+ (input->fd + 1),
+ &ready_to_read,
+ (fd_set *) NULL,
+ (fd_set *) NULL,
+ (input->timed_out) ? NULL : &(curr_timeout)
+ );
+
+ if (errno != 0)
{
- return -1;
- }
+ RELABSD_ERROR
+ (
+ "Unable to wait for timeout: %s (errno: %d).",
+ strerror(errno),
+ errno
+ );
+
+ if (errno == EINTR)
+ {
+ /* Signal interruption? */
+ }
+ else
+ {
+ /* TODO: error message */
+ }
- if (relabsd_config_parse(&conf, argc, argv) < 0)
- {
- return -2;
- }
+ errno = old_errno;
- if (relabsd_input_open(&input, &conf) < 0)
- {
- return -3;
+ return -1;
}
- if (relabsd_device_create(&dev, &conf) < 0)
+ if (ready_fds == -1)
{
- return -4;
- }
-
- convert_input(&conf, &input, &dev);
+ /* TODO: error message */
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating...");
+ RELABSD_S_ERROR
+ (
+ "Unable to wait for timeout, yet errno was not set to anything."
+ );
- relabsd_device_destroy(&dev);
- relabsd_input_close(&input);
+ errno = old_errno;
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done.");
+ return -1;
+ }
- return 0;
-}
-*/
+ RELABSD_ERROR
+ (
+ "Input is ready, ready_fds = %d", ready_fds
+ );
-int relabsd_server_conversion_loop
-(
- struct relabsd_server server [const static 1]
-)
-{
- return 0;
+ return ready_fds;
}
diff --git a/src/server/interruption.c b/src/server/interruption.c
new file mode 100644
index 0000000..6eb7827
--- /dev/null
+++ b/src/server/interruption.c
@@ -0,0 +1,23 @@
+static int RELABSD_RUN = 1;
+
+static void interrupt (int unused_mandatory_parameter)
+{
+ RELABSD_RUN = 0;
+
+ RELABSD_S_WARNING("Interrupted, will exit at the next input device event.");
+}
+
+static int set_signal_handlers ()
+{
+ RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers.");
+
+ if (signal(SIGINT, interrupt) == SIG_ERR)
+ {
+ RELABSD_S_FATAL("Unable to set the SIGINT signal handler.");
+
+ return -1;
+ }
+
+ return 0;
+}
+