summaryrefslogtreecommitdiff
path: root/rcm-server-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'rcm-server-main.c')
-rw-r--r--rcm-server-main.c163
1 files changed, 148 insertions, 15 deletions
diff --git a/rcm-server-main.c b/rcm-server-main.c
index 4a0adbc..4d23f89 100644
--- a/rcm-server-main.c
+++ b/rcm-server-main.c
@@ -649,6 +649,58 @@ out:
return sd_bus_error_set_errno(error, r);
}
+static void
+lirc_write(int fd, const uint32_t *v, unsigned count)
+{
+ unsigned nv[count];
+ unsigned i;
+ size_t l = count * sizeof(uint32_t);
+
+ for (i = 0; i < count; i++)
+ nv[i] = v[i];
+
+ printf("Write to lirc fd of %zu bytes returned %zi errno is %i aka %s\n",
+ l, write(fd, nv, l), errno, strerror(errno));
+}
+
+static int
+method_transmit(sd_bus_message *m, void *userdata, sd_bus_error *error)
+{
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ struct manager *mgr = userdata;
+ struct device *dev;
+ const void *v;
+ size_t l;
+ int r;
+ const uint32_t *values;
+ size_t count;
+
+ printf("Transmit method called\n");
+ dev = find_device_by_path(mgr, sd_bus_message_get_path(m));
+ if (!dev) {
+ sd_bus_error_set_const(error, "org.gnome.RemoteControlManager.InvalidDevice", "Sorry, invalid device");
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_read_array(m, SD_BUS_TYPE_UINT32, &v, &l);
+ if (r < 0) {
+ goto out;
+ } else if (r == 0 || l % sizeof(uint32_t) != 0) {
+ r = -EBADMSG;
+ goto out;
+ }
+
+ values = v;
+ count = l / sizeof(uint32_t);
+ lirc_write(dev->lirc_fd, values, count);
+
+
+ return sd_bus_reply_method_return(m, NULL);
+
+out:
+ return sd_bus_error_set_errno(error, r);
+}
+
static const sd_bus_vtable device_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("SysName", "s", property_get, 0, 0),
@@ -660,6 +712,7 @@ static const sd_bus_vtable device_vtable[] = {
SD_BUS_METHOD("ListKeymaps", NULL, "as", method_listkeymaps, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetKeymap", "s", "ssqqaa{sv}aa{sv}", method_getkeymap, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetKeymap", "sssqqaa{sv}aa{sv}", NULL, method_setkeymap, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Transmit", "au", NULL, method_transmit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("KeyPressed", "sts", 0),
SD_BUS_SIGNAL("KeyReleased", "s", 0),
SD_BUS_VTABLE_END
@@ -684,6 +737,63 @@ remove_device(struct manager *mgr, struct udev_device *udev)
}
}
+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)
{
@@ -693,7 +803,6 @@ add_device(struct manager *mgr, struct udev_device *udev)
struct device *device;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
- struct udev_device *evdev;
int r;
name = udev_device_get_sysname(udev);
@@ -714,7 +823,9 @@ add_device(struct manager *mgr, struct udev_device *udev)
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;
if (keymaps_load(device) < 0) {
fprintf(stderr, "failed to load keymaps: %m\n");
@@ -726,12 +837,15 @@ add_device(struct manager *mgr, struct udev_device *udev)
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) {
@@ -739,29 +853,47 @@ add_device(struct manager *mgr, struct udev_device *udev)
continue;
}
- evdev = udev_device_new_from_syspath(mgr->udev, path);
- if (!evdev) {
+ 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(evdev);
+ devnode = udev_device_get_devnode(udev_dev);
if (!devnode) {
- printf("Failed to determine evdev devnode\n");
- udev_device_unref(evdev);
- continue;
+ printf("Failed to determine udev_dev devnode\n");
+ goto next;
}
- r = evdev_setup(device, devnode);
- if (r < 0) {
- printf("Failed to setup evdev: %s\n", devnode);
- device->error = "Error: Failed to setup evdev";
- device->input_name = NULL;
- udev_device_unref(evdev);
- continue;
+ 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;
}
- udev_device_unref(evdev);
+next:
+ udev_device_unref(udev_dev);
}
udev_enumerate_unref(enumerate);
@@ -793,6 +925,7 @@ add_device(struct manager *mgr, struct udev_device *udev)
printf("\tDriver : %s\n", device->driver_name);
printf("\tKernel map: %s\n", device->keymap_name);
printf("\tDevnode 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"));