summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--rcm-server-main.c307
-rw-r--r--rcm-server-udev.c332
-rw-r--r--rcm-server-udev.h9
4 files changed, 345 insertions, 307 deletions
diff --git a/Makefile b/Makefile
index 7c33df0..fc38291 100644
--- a/Makefile
+++ b/Makefile
@@ -19,8 +19,8 @@ RCM_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCM
RCM_LDFLAGS = ${GENERIC_LDFLAGS} ${EXTRA_LDFLAGS} $(shell pkg-config --libs ${RCM_PACKAGES})
RCM_COMPILE = $(CC) $(RCM_CFLAGS)
RCM_LINK = $(CC) $(RCM_CFLAGS) $(RCM_LDFLAGS)
-RCM_OBJECTS = rcm-server-main.o rcm-server-keymap.o rcm-server-evdev.o rcm-server-kdb.o shared.o
-RCM_HEADERS = rcm-server-main.h rcm-server-keymap.h rcm-server-evdev.h rcm-server-kdb.h utils.h $(COMMON_HEADERS)
+RCM_OBJECTS = rcm-server-main.o rcm-server-keymap.o rcm-server-udev.o rcm-server-evdev.o rcm-server-kdb.o shared.o
+RCM_HEADERS = rcm-server-main.h rcm-server-keymap.h rcm-server-udev.h rcm-server-evdev.h rcm-server-kdb.h utils.h $(COMMON_HEADERS)
RCC_PACKAGES = gtk+-3.0 gmodule-2.0
RCC_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCC_PACKAGES})
diff --git a/rcm-server-main.c b/rcm-server-main.c
index d2f0160..7aadb69 100644
--- a/rcm-server-main.c
+++ b/rcm-server-main.c
@@ -2,7 +2,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
-#include <libudev.h>
#include <unistd.h>
#include <string.h>
#include <systemd/sd-bus.h>
@@ -15,6 +14,7 @@
#include "utils.h"
#include "shared.h"
#include "rcm-server-main.h"
+#include "rcm-server-udev.h"
#include "rcm-server-keymap.h"
#include "rcm-server-evdev.h"
#include "rcm-server-kdb.h"
@@ -854,308 +854,6 @@ static const sd_bus_vtable device_vtable[] = {
SD_BUS_VTABLE_END
};
-static void
-remove_device(struct manager *mgr, struct udev_device *udev)
-{
- const char *name;
- struct device *device;
-
- name = udev_device_get_sysname(udev);
- printf("Asked to remove device %s\n", name);
-
- list_for_each_entry(device, &mgr->devices, list) {
- if (strcmp(device->name, name))
- continue;
- list_del(&device->list);
- sd_bus_emit_object_removed(mgr->bus, device->path);
- mgr->num_devices--;
- break;
- }
-}
-
-static int
-lirc_read(sd_event_source *s, int fd, uint32_t revents, void *userdata)
-{
- struct device *device = userdata;
- uint8_t buf[100];
- ssize_t bytes_read;
-
- if (fd != device->lirc_fd)
- fprintf(stderr, "lirc fd mismatch: %i != %i\n", device->lirc_fd, fd);
-
- if (revents & EPOLLHUP) {
- fprintf(stderr, "lirc connection closed!\n");
- close(fd);
- device->lirc_fd = -1;
- return 0;
- }
-
- if (!(revents & EPOLLIN)) {
- fprintf(stderr, "unexpected lirc event: %" PRIu32 "\n", revents);
- return 0;
- }
-
- while ((bytes_read = read(fd, buf, sizeof(buf))) > 0)
- printf("Read %zi bytes from lirc dev\n", bytes_read);
-
- return 0;
-}
-
-static int
-lirc_setup(struct device *device, const char *path)
-{
- if (!device)
- return -EINVAL;
-
- if (device->lirc_fd >= 0) {
- printf("Multiple lirc devices!?\n");
- return 0;
- }
-
- device->lirc_fd = open(path, O_RDWR | O_NONBLOCK);
- if (device->lirc_fd < 0) {
- printf("Failed to open lirc device %s: %s\n", path, strerror(errno));
- return -errno;
- }
-
- if (sd_event_add_io(device->mgr->event, &device->lirc_ev,
- device->lirc_fd, EPOLLIN, lirc_read, device) < 0) {
- printf("Failed to add event source for lirc device %s: %s\n",
- path, strerror(errno));
- close(device->lirc_fd);
- device->lirc_fd = -1;
- return -errno;
- }
-
- return 0;
-}
-
-static void
-add_device(struct manager *mgr, struct udev_device *udev)
-{
- const char *name;
- const char *str;
- char *path;
- struct device *device;
- struct udev_enumerate *enumerate;
- struct udev_list_entry *devices, *dev_list_entry;
- int r;
-
- name = udev_device_get_sysname(udev);
- if (asprintf(&path, "/org/gnome/RemoteControlManager/%s", name) < 0) {
- fprintf(stderr, "asprintf failed: %m\n");
- return;
- }
-
- device = malloc(sizeof(*device));
- if (!device) {
- fprintf(stderr, "malloc failed: %m\n");
- free(path);
- return;
- }
-
- list_init(&device->keymaps);
- device->mgr = mgr;
- device->path = path;
- device->name = device->path + strlen("/org/gnome/RemoteControlManager/");
- device->evdev_fd = -1;
- device->lirc_fd = -1;
- device->error = NULL;
- device->input_name = NULL;
- device->driver_name = NULL;
- device->keymap_name = NULL;
- device->dev_name = NULL;
-
- if (keymaps_load(device) < 0) {
- fprintf(stderr, "failed to load keymaps: %m\n");
- free(path);
- free(device);
- return;
- }
-
- enumerate = udev_enumerate_new(mgr->udev);
- udev_enumerate_add_match_parent(enumerate, udev);
- udev_enumerate_add_match_sysname(enumerate, "event*");
- udev_enumerate_add_match_sysname(enumerate, "lirc*");
- udev_enumerate_scan_devices(enumerate);
- devices = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(dev_list_entry, devices) {
- const char *path;
- struct udev_device *udev_dev;
- const char *devnode;
- const char *subsys;
-
- path = udev_list_entry_get_name(dev_list_entry);
- if (!path) {
- printf("Failed to get udev name\n");
- continue;
- }
-
- udev_dev = udev_device_new_from_syspath(mgr->udev, path);
- if (!udev_dev) {
- printf("Failed to create udev device\n");
- continue;
- }
-
- devnode = udev_device_get_devnode(udev_dev);
- if (!devnode) {
- printf("Failed to determine udev_dev devnode\n");
- goto next;
- }
-
- subsys = udev_device_get_subsystem(udev_dev);
- if (!subsys) {
- printf("Failed to determine udev_dev subsystem\n");
- goto next;
- }
-
- if (!strcmp(subsys, "input")) {
- r = evdev_setup(device, devnode);
- if (r < 0) {
- printf("Failed to setup evdev: %s\n", devnode);
- device->error = "Error: Failed to setup evdev";
- goto next;
- }
-
- } else if (!strcmp(subsys, "lirc")) {
- r = lirc_setup(device, devnode);
- if (r < 0) {
- printf("Failed to setup lirc: %s\n", devnode);
- device->error = "Error: Failed to setup lirc";
- goto next;
- }
-
- } else {
- printf("Unknown subsystem, ignored %s\n", devnode);
- goto next;
- }
-
-next:
- udev_device_unref(udev_dev);
- }
- udev_enumerate_unref(enumerate);
-
- str = udev_device_get_sysattr_value(udev, "uevent");
- if (str) {
- char tmp[strlen(str) + 1];
- char *token;
-
- strcpy(tmp, str);
-
- for (token = strtok(tmp, "\n"); token; token = strtok(NULL, "\n")) {
- if (!strncmp(token, "DRV_NAME=", strlen("DRV_NAME=")))
- device->driver_name = strdup(token + strlen("DRV_NAME="));
- else if (!strncmp(token, "NAME=", strlen("NAME=")))
- device->keymap_name = strdup(token + strlen("NAME="));
- else if (!strncmp(token, "DEVNAME=", strlen("DEVNAME=")))
- device->dev_name = strdup(token + strlen("DEVNAME="));
- else if (!strncmp(token, "MAJOR=", strlen("MAJOR=")))
- continue;
- else if (!strncmp(token, "MINOR=", strlen("MINOR=")))
- continue;
- else
- printf("Unused uevent: %s\n", token);
- }
- }
-
- printf("Adding Device Object\n");
- printf("\tPath : %s\n", udev_device_get_syspath(udev));
- printf("\tNode : %s\n", udev_device_get_devnode(udev));
- printf("\tSubsystem : %s\n", udev_device_get_subsystem(udev));
- printf("\tDevtype : %s\n", udev_device_get_devtype(udev));
- printf("\tAction : %s\n", udev_device_get_action(udev));
- printf("\tName : %s\n", device->name);
- printf("\tInput name: %s\n", device->input_name);
- printf("\tDriver : %s\n", device->driver_name);
- printf("\tKernel map: %s\n", device->keymap_name);
- printf("\tDev name : %s\n", device->dev_name);
- printf("\tevdev fd : %i\n", device->evdev_fd);
- printf("\tLIRC fd : %i\n", device->lirc_fd);
- printf("\tDBUS path : %s\n", device->path);
- printf("\tProtocols : %s\n",
- udev_device_get_sysattr_value(udev, "protocols"));
-
- list_add(&device->list, &mgr->devices);
- mgr->num_devices++;
-
- sd_bus_emit_object_added(mgr->bus, path);
-}
-
-static int
-udev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata)
-{
- struct manager *mgr = userdata;
- struct udev_device *dev;
-
- if (revents & EPOLLHUP) {
- fprintf(stderr, "udev connection closed!\n");
- return 0;
- }
-
- if (!(revents & EPOLLIN)) {
- fprintf(stderr, "unexpected udev event: %" PRIu32 "\n", revents);
- return 0;
- }
-
- while ((dev = udev_monitor_receive_device(mgr->udev_mon))) {
- printf("Read device: %s\n", udev_device_get_syspath(dev));
- if (!strcmp(udev_device_get_action(dev), "add"))
- add_device(mgr, dev);
- else if (!strcmp(udev_device_get_action(dev), "remove"))
- remove_device(mgr, dev);
- udev_device_unref(dev);
- }
-
- return 1;
-}
-
-static int
-udev_setup(struct manager *mgr)
-{
- struct udev_enumerate *enumerate;
- struct udev_list_entry *devices, *dev_list_entry;
- struct udev_device *dev;
-
- mgr->udev = udev_new();
- if (!mgr->udev)
- return -ENOMEM;
-
- mgr->udev_mon = udev_monitor_new_from_netlink(mgr->udev, "udev");
- udev_monitor_filter_add_match_subsystem_devtype(mgr->udev_mon, "rc", NULL);
- udev_monitor_enable_receiving(mgr->udev_mon);
-
- enumerate = udev_enumerate_new(mgr->udev);
- udev_enumerate_add_match_subsystem(enumerate, "rc");
- udev_enumerate_scan_devices(enumerate);
- devices = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(dev_list_entry, devices) {
- const char *path;
-
- path = udev_list_entry_get_name(dev_list_entry);
- if (!path) {
- printf("Failed to get udev name\n");
- continue;
- }
-
- dev = udev_device_new_from_syspath(mgr->udev, path);
- if (!dev) {
- printf("Failed to create udev device\n");
- continue;
- }
-
- add_device(mgr, dev);
-
- udev_device_unref(dev);
- }
- udev_enumerate_unref(enumerate);
-
- return sd_event_add_io(mgr->event, &mgr->udev_ev,
- udev_monitor_get_fd(mgr->udev_mon),
- EPOLLIN, udev_read, mgr);
-}
-
static int
enumerator(sd_bus *bus, const char *path, void *userdata, char ***retnodes, sd_bus_error *error)
{
@@ -1194,8 +892,7 @@ free_manager(struct manager *mgr) {
sd_event_source_unref(mgr->udev_ev);
sd_bus_detach_event(mgr->bus);
sd_event_unref(mgr->event);
- udev_monitor_unref(mgr->udev_mon);
- udev_unref(mgr->udev);
+ udev_close(mgr);
while (!list_empty(&mgr->devices)) {
struct device *dev = list_first_entry(&mgr->devices, typeof(*dev), list);
diff --git a/rcm-server-udev.c b/rcm-server-udev.c
new file mode 100644
index 0000000..d29b4d9
--- /dev/null
+++ b/rcm-server-udev.c
@@ -0,0 +1,332 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <libudev.h>
+#include <unistd.h>
+#include <string.h>
+#include <systemd/sd-bus.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "utils.h"
+#include "shared.h"
+#include "rcm-server-main.h"
+#include "rcm-server-keymap.h"
+#include "rcm-server-evdev.h"
+#include "rcm-server-udev.h"
+
+static void
+remove_device(struct manager *mgr, struct udev_device *udev)
+{
+ const char *name;
+ struct device *device;
+
+ name = udev_device_get_sysname(udev);
+ printf("Asked to remove device %s\n", name);
+
+ list_for_each_entry(device, &mgr->devices, list) {
+ if (strcmp(device->name, name))
+ continue;
+ list_del(&device->list);
+ sd_bus_emit_object_removed(mgr->bus, device->path);
+ mgr->num_devices--;
+ break;
+ }
+}
+
+static int
+lirc_read(sd_event_source *s, int fd, uint32_t revents, void *userdata)
+{
+ struct device *device = userdata;
+ uint8_t buf[100];
+ ssize_t bytes_read;
+
+ if (fd != device->lirc_fd)
+ fprintf(stderr, "lirc fd mismatch: %i != %i\n", device->lirc_fd, fd);
+
+ if (revents & EPOLLHUP) {
+ fprintf(stderr, "lirc connection closed!\n");
+ close(fd);
+ device->lirc_fd = -1;
+ return 0;
+ }
+
+ if (!(revents & EPOLLIN)) {
+ fprintf(stderr, "unexpected lirc event: %" PRIu32 "\n", revents);
+ return 0;
+ }
+
+ while ((bytes_read = read(fd, buf, sizeof(buf))) > 0)
+ printf("Read %zi bytes from lirc dev\n", bytes_read);
+
+ return 0;
+}
+
+static int
+lirc_setup(struct device *device, const char *path)
+{
+ if (!device)
+ return -EINVAL;
+
+ if (device->lirc_fd >= 0) {
+ printf("Multiple lirc devices!?\n");
+ return 0;
+ }
+
+ device->lirc_fd = open(path, O_RDWR | O_NONBLOCK);
+ if (device->lirc_fd < 0) {
+ printf("Failed to open lirc device %s: %s\n", path, strerror(errno));
+ return -errno;
+ }
+
+ if (sd_event_add_io(device->mgr->event, &device->lirc_ev,
+ device->lirc_fd, EPOLLIN, lirc_read, device) < 0) {
+ printf("Failed to add event source for lirc device %s: %s\n",
+ path, strerror(errno));
+ close(device->lirc_fd);
+ device->lirc_fd = -1;
+ return -errno;
+ }
+
+ return 0;
+}
+
+static void
+add_device(struct manager *mgr, struct udev_device *udev)
+{
+ const char *name;
+ const char *str;
+ char *path;
+ struct device *device;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ int r;
+
+ name = udev_device_get_sysname(udev);
+ if (asprintf(&path, "/org/gnome/RemoteControlManager/%s", name) < 0) {
+ fprintf(stderr, "asprintf failed: %m\n");
+ return;
+ }
+
+ device = malloc(sizeof(*device));
+ if (!device) {
+ fprintf(stderr, "malloc failed: %m\n");
+ free(path);
+ return;
+ }
+
+ list_init(&device->keymaps);
+ device->mgr = mgr;
+ device->path = path;
+ device->name = device->path + strlen("/org/gnome/RemoteControlManager/");
+ device->evdev_fd = -1;
+ device->lirc_fd = -1;
+ device->error = NULL;
+ device->input_name = NULL;
+ device->driver_name = NULL;
+ device->keymap_name = NULL;
+ device->dev_name = NULL;
+
+ if (keymaps_load(device) < 0) {
+ fprintf(stderr, "failed to load keymaps: %m\n");
+ free(path);
+ free(device);
+ return;
+ }
+
+ enumerate = udev_enumerate_new(mgr->udev);
+ udev_enumerate_add_match_parent(enumerate, udev);
+ udev_enumerate_add_match_sysname(enumerate, "event*");
+ udev_enumerate_add_match_sysname(enumerate, "lirc*");
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ const char *path;
+ struct udev_device *udev_dev;
+ const char *devnode;
+ const char *subsys;
+
+ path = udev_list_entry_get_name(dev_list_entry);
+ if (!path) {
+ printf("Failed to get udev name\n");
+ continue;
+ }
+
+ udev_dev = udev_device_new_from_syspath(mgr->udev, path);
+ if (!udev_dev) {
+ printf("Failed to create udev device\n");
+ continue;
+ }
+
+ devnode = udev_device_get_devnode(udev_dev);
+ if (!devnode) {
+ printf("Failed to determine udev_dev devnode\n");
+ goto next;
+ }
+
+ subsys = udev_device_get_subsystem(udev_dev);
+ if (!subsys) {
+ printf("Failed to determine udev_dev subsystem\n");
+ goto next;
+ }
+
+ if (!strcmp(subsys, "input")) {
+ r = evdev_setup(device, devnode);
+ if (r < 0) {
+ printf("Failed to setup evdev: %s\n", devnode);
+ device->error = "Error: Failed to setup evdev";
+ goto next;
+ }
+
+ } else if (!strcmp(subsys, "lirc")) {
+ r = lirc_setup(device, devnode);
+ if (r < 0) {
+ printf("Failed to setup lirc: %s\n", devnode);
+ device->error = "Error: Failed to setup lirc";
+ goto next;
+ }
+
+ } else {
+ printf("Unknown subsystem, ignored %s\n", devnode);
+ goto next;
+ }
+
+next:
+ udev_device_unref(udev_dev);
+ }
+ udev_enumerate_unref(enumerate);
+
+ str = udev_device_get_sysattr_value(udev, "uevent");
+ if (str) {
+ char tmp[strlen(str) + 1];
+ char *token;
+
+ strcpy(tmp, str);
+
+ for (token = strtok(tmp, "\n"); token; token = strtok(NULL, "\n")) {
+ if (!strncmp(token, "DRV_NAME=", strlen("DRV_NAME=")))
+ device->driver_name = strdup(token + strlen("DRV_NAME="));
+ else if (!strncmp(token, "NAME=", strlen("NAME=")))
+ device->keymap_name = strdup(token + strlen("NAME="));
+ else if (!strncmp(token, "DEVNAME=", strlen("DEVNAME=")))
+ device->dev_name = strdup(token + strlen("DEVNAME="));
+ else if (!strncmp(token, "MAJOR=", strlen("MAJOR=")))
+ continue;
+ else if (!strncmp(token, "MINOR=", strlen("MINOR=")))
+ continue;
+ else
+ printf("Unused uevent: %s\n", token);
+ }
+ }
+
+ printf("Adding Device Object\n");
+ printf("\tPath : %s\n", udev_device_get_syspath(udev));
+ printf("\tNode : %s\n", udev_device_get_devnode(udev));
+ printf("\tSubsystem : %s\n", udev_device_get_subsystem(udev));
+ printf("\tDevtype : %s\n", udev_device_get_devtype(udev));
+ printf("\tAction : %s\n", udev_device_get_action(udev));
+ printf("\tName : %s\n", device->name);
+ printf("\tInput name: %s\n", device->input_name);
+ printf("\tDriver : %s\n", device->driver_name);
+ printf("\tKernel map: %s\n", device->keymap_name);
+ printf("\tDev name : %s\n", device->dev_name);
+ printf("\tevdev fd : %i\n", device->evdev_fd);
+ printf("\tLIRC fd : %i\n", device->lirc_fd);
+ printf("\tDBUS path : %s\n", device->path);
+ printf("\tProtocols : %s\n",
+ udev_device_get_sysattr_value(udev, "protocols"));
+
+ list_add(&device->list, &mgr->devices);
+ mgr->num_devices++;
+
+ sd_bus_emit_object_added(mgr->bus, path);
+}
+
+static int
+udev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata)
+{
+ struct manager *mgr = userdata;
+ struct udev_device *dev;
+
+ if (revents & EPOLLHUP) {
+ fprintf(stderr, "udev connection closed!\n");
+ return 0;
+ }
+
+ if (!(revents & EPOLLIN)) {
+ fprintf(stderr, "unexpected udev event: %" PRIu32 "\n", revents);
+ return 0;
+ }
+
+ while ((dev = udev_monitor_receive_device(mgr->udev_mon))) {
+ printf("Read device: %s\n", udev_device_get_syspath(dev));
+ if (!strcmp(udev_device_get_action(dev), "add"))
+ add_device(mgr, dev);
+ else if (!strcmp(udev_device_get_action(dev), "remove"))
+ remove_device(mgr, dev);
+ udev_device_unref(dev);
+ }
+
+ return 1;
+}
+
+int
+udev_setup(struct manager *mgr)
+{
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ struct udev_device *dev;
+
+ mgr->udev = udev_new();
+ if (!mgr->udev)
+ return -ENOMEM;
+
+ mgr->udev_mon = udev_monitor_new_from_netlink(mgr->udev, "udev");
+ udev_monitor_filter_add_match_subsystem_devtype(mgr->udev_mon, "rc", NULL);
+ udev_monitor_enable_receiving(mgr->udev_mon);
+
+ enumerate = udev_enumerate_new(mgr->udev);
+ udev_enumerate_add_match_subsystem(enumerate, "rc");
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ const char *path;
+
+ path = udev_list_entry_get_name(dev_list_entry);
+ if (!path) {
+ printf("Failed to get udev name\n");
+ continue;
+ }
+
+ dev = udev_device_new_from_syspath(mgr->udev, path);
+ if (!dev) {
+ printf("Failed to create udev device\n");
+ continue;
+ }
+
+ add_device(mgr, dev);
+
+ udev_device_unref(dev);
+ }
+ udev_enumerate_unref(enumerate);
+
+ return sd_event_add_io(mgr->event, &mgr->udev_ev,
+ udev_monitor_get_fd(mgr->udev_mon),
+ EPOLLIN, udev_read, mgr);
+}
+
+void
+udev_close(struct manager *mgr)
+{
+ if (!mgr)
+ return;
+
+ udev_monitor_unref(mgr->udev_mon);
+ udev_unref(mgr->udev);
+}
+
diff --git a/rcm-server-udev.h b/rcm-server-udev.h
new file mode 100644
index 0000000..58ccd1b
--- /dev/null
+++ b/rcm-server-udev.h
@@ -0,0 +1,9 @@
+#ifndef foorcmserverudevhfoo
+#define foorcmserverudevhfoo
+
+int udev_setup(struct manager *mgr);
+
+void udev_close(struct manager *mgr);
+
+#endif
+