From 063c69303bdacf4ce0508ba000b3f7ecc657be28 Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Wed, 31 Aug 2022 00:54:56 +0200 Subject: [PATCH] client mostly done --- .clang-format | 2 + Makefile | 2 +- client.c | 319 +++++++++++++++++++++++++++++++++++++++++++++++++- client.h | 2 +- hid.c | 23 ++-- hid.h | 8 +- main.c | 13 +- main.h | 2 +- net.c | 98 ++++++++-------- net.h | 31 ++--- server.c | 48 ++++++-- server.h | 2 +- util.c | 4 +- util.h | 2 +- vec.c | 1 + vec.h | 2 +- 16 files changed, 450 insertions(+), 109 deletions(-) diff --git a/.clang-format b/.clang-format index 44bced6..4ec942d 100644 --- a/.clang-format +++ b/.clang-format @@ -1,6 +1,8 @@ +# vi:ft=yaml BasedOnStyle: LLVM IndentWidth: 4 AlignConsecutiveDeclarations: true AlignConsecutiveAssignments: true PointerAlignment: Right ColumnLimit: 110 +IncludeBlocks: Regroup diff --git a/Makefile b/Makefile index 654c8c8..ec17a62 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ Q=@ CC=gcc -CFLAGS=-g -Wall -Wno-format-truncation -pthread +CFLAGS=-g -Wall -Wno-format-truncation -pthread -DJSFW_DEV LDFLAGS= BUILD_DIR=./objects BIN=jsfw diff --git a/client.c b/client.c index 34f5e46..32867f6 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,319 @@ #include "client.h" -#include -void client_run(char *address, uint16_t port) {} +#include "net.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + int fd; + MessageDeviceInfo info; +} VirtualDevice; + +#ifdef JSFW_DEV +// Path for dev environment (no root) +const char *FIFO_PATH = "/tmp/jsfw_fifo"; +#else +const char *FIFO_PATH = "/run/jsfw_fifo"; +#endif +const int CONN_RETRY_DELAY = 5; +// Constant for the virtual device +const uint16_t VIRT_VENDOR = 0x6969; +const uint16_t VIRT_PRODUCT = 0x0420; +const uint16_t VIRT_VERSION = 1; +const char *VIRT_NAME = "JSFW Virtual Device"; + +static int fifo_attempt = 0; + +static struct sockaddr_in server_addr = {}; +static char server_addrp[64] = {}; +static uint16_t server_port = -1; + +static struct pollfd poll_fds[2]; +static struct pollfd *fifo_poll = &poll_fds[0]; +static struct pollfd *socket_poll = &poll_fds[1]; +static int fifo = -1; +static int sock = -1; +// static to avoid having this on the stack because a message is about 2kb in memory +static Message message; +static VirtualDevice device = {}; + +static inline bool device_exists() { return device.fd > 0; } + +void device_destroy() { + if (!device_exists()) { + return; + } + + ioctl(device.fd, UI_DEV_DESTROY); + close(device.fd); + device.fd = -1; + printf("CLIENT: Destroyed device\n"); +} + +void device_init(MessageDeviceInfo *dev) { + device_destroy(); + + int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + if (fd < 0) { + perror("CLIENT: Error while opening /dev/uinput, "); + exit(1); + } + + // Abs + if (dev->abs_count > 0) { + ioctl(fd, UI_SET_EVBIT, EV_ABS); + for (int i = 0; i < dev->abs_count; i++) { + struct uinput_abs_setup setup; + setup.code = dev->abs_id[i]; + setup.absinfo.minimum = dev->abs_min[i]; + setup.absinfo.maximum = dev->abs_max[i]; + setup.absinfo.fuzz = dev->abs_fuzz[i]; + setup.absinfo.flat = dev->abs_flat[i]; + setup.absinfo.resolution = dev->abs_res[i]; + setup.absinfo.value = 0; + ioctl(fd, UI_ABS_SETUP, &setup); + } + } + + // Rel + if (dev->rel_count > 0) { + ioctl(fd, UI_SET_EVBIT, EV_REL); + for (int i = 0; i < dev->rel_count; i++) { + ioctl(fd, UI_SET_RELBIT, dev->rel_id[i]); + } + } + + // Key + if (dev->key_count > 0) { + ioctl(fd, UI_SET_EVBIT, EV_KEY); + for (int i = 0; i < dev->key_count; i++) { + ioctl(fd, UI_SET_KEYBIT, dev->key_id[i]); + } + } + + struct uinput_setup setup = {}; + + setup.id.bustype = BUS_VIRTUAL; + setup.id.vendor = VIRT_VENDOR; + setup.id.product = VIRT_PRODUCT; + setup.id.version = VIRT_VERSION; + strncpy(setup.name, VIRT_NAME, UINPUT_MAX_NAME_SIZE); + + ioctl(fd, UI_DEV_SETUP, &setup); + ioctl(fd, UI_DEV_CREATE); + + device.fd = fd; + memcpy(&device.info, dev, sizeof(MessageDeviceInfo)); + printf("CLIENT: Created device (abs: %d, rel: %d, key: %d)\n", dev->abs_count, dev->rel_count, + dev->key_count); +} + +int device_emit(uint16_t type, uint16_t id, uint32_t value) { + struct input_event event = {}; + + event.type = type; + event.code = id; + event.value = value; + + return write(device.fd, &event, sizeof(event)) != sizeof(event); +} + +void device_handle_report(MessageDeviceReport *report) { + if (!device_exists()) { + printf("CLIENT: Got report but device info\n"); + return; + } + + if (report->abs_count != device.info.abs_count || report->rel_count != device.info.rel_count || + report->key_count != device.info.key_count) { + printf("CLIENT: Report doesn't match with device info\n"); + return; + } + + for (int i = 0; i < report->abs_count; i++) { + if (device_emit(EV_ABS, device.info.abs_id[i], report->abs[i]) != 0) + printf("CLIENT: Error writing abs event to uinput\n"); + } + + for (int i = 0; i < report->rel_count; i++) { + if (device_emit(EV_REL, device.info.rel_id[i], report->rel[i]) != 0) + printf("CLIENT: Error writing rel event to uinput\n"); + } + + for (int i = 0; i < report->key_count; i++) { + if (device_emit(EV_KEY, device.info.key_id[i], (uint32_t)(!report->key[i]) - 1 ) != 0) + printf("CLIENT: Error writing key event to uinput\n"); + } + + device_emit(EV_SYN, 0, 0); +} + +void setup_fifo(); + +void open_fifo() { + close(fifo); + fifo = open(FIFO_PATH, O_RDONLY | O_NONBLOCK); + if (fifo < 0 && fifo_attempt == 0) { + fifo_attempt++; + unlink(FIFO_PATH); + setup_fifo(); + } else if (fifo < 0) { + panicf("CLIENT: Couldn't open fifo, aborting\n"); + } +} + +void setup_fifo() { + mode_t prev = umask(0); + mkfifo(FIFO_PATH, 0666); + umask(prev); + + open_fifo(); + + fifo_poll->fd = fifo; + fifo_poll->events = POLLIN; +} + +void connect_server() { + while (1) { + if (sock > 0) { + device_destroy(); + shutdown(sock, SHUT_RDWR); + close(sock); + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + panicf("Couldn't create socket\n"); + + if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) { + printf("CLIENT: Couldn't connect to %s:%d, retrying in %ds\n", server_addrp, server_port, + CONN_RETRY_DELAY); + struct timespec ts = {}; + ts.tv_sec = CONN_RETRY_DELAY; + nanosleep(&ts, NULL); + continue; + } + // Set non blocking + fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); + socket_poll->fd = sock; + printf("CLIENT: Connected !\n"); + return; + } +} + +void setup_server(char *address, uint16_t port) { + // setup address + server_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, address, &server_addr.sin_addr) == 0) + printf("CLIENT: failed to parse address '%s', defaulting to 0.0.0.0 (localhost)\n", address); + inet_ntop(AF_INET, &server_addr.sin_addr, server_addrp, 64); + server_port = port; + server_addr.sin_port = htons(port); + + socket_poll->events = POLLIN; + + connect_server(); +} + +void early_checks() { + int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + if (fd < 0) { + perror("CLIENT: Can't open /dev/uinput, aborting now: "); + exit(1); + } + close(fd); +} + +void client_run(char *address, uint16_t port) { + // Device doesn't exist yet + device.fd = -1; + + early_checks(); + setup_fifo(); + setup_server(address, port); + + uint8_t buf[2049]; + while (1) { + int rc = poll(poll_fds, 2, -1); + if (rc < 0) { + perror("CLIENT: Error on poll, "); + exit(1); + } + + if (fifo_poll->revents & POLLHUP || fifo_poll->revents & POLLERR) { + // Reopen fifo + open_fifo(); + } else if (fifo_poll->revents & POLLIN) { + int len = read(fifo, buf, 2048); + if (len <= 0) { + // This shouldn't ever happen as the poll already checks for the kind of error that would + // cause len to be <= 0 + printf("CLIENT: supposedly unreachable code reached\n"); + open_fifo(); + } else { + // We've got data from the fifo + // TODO: parse and handle that + buf[len] = '\0'; + printf("CLIENT: Got fifo message:\n%s\n", buf); + } + } + + // A broken or closed socket produces a POLLIN event, so we check for error on the recv + if (socket_poll->revents & POLLIN) { + int len = recv(sock, buf, 2048, 0); + if (len <= 0) { + printf("CLIENT: Lost connection to server, reconnecting\n"); + shutdown(sock, SHUT_RDWR); + connect_server(); + // we can continue here because there's nothing after, unlike above for fifo (this reduces + // indentation) + continue; + } + + // We've got data from the server + if (msg_deserialize(buf, len, &message) != 0) { + printf("CLIENT: Couldn't parse message (code: %d, len: %d)\n", buf[0], len); + int l = len > 100 ? 100 : len; + for(int i = 0; i < l; i++) { + printf("%02x", buf[i]); + } + if(len > 100) { + printf(" ... %d more bytes", len - 100); + } + printf("\n"); + continue; + } + + if (message.code == DeviceInfo) { + + if (device_exists()) + printf("CLIENT: Got more than one device info\n"); + device_init((MessageDeviceInfo *)&message); + + } else if (message.code == DeviceReport) { + + device_handle_report((MessageDeviceReport *)&message); + + } else { + printf("CLIENT: Illegal message\n"); + } + } + } +} diff --git a/client.h b/client.h index 4eb3f0c..896e4b5 100644 --- a/client.h +++ b/client.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef CLIENT_H #define CLIENT_H #include diff --git a/hid.c b/hid.c index bb2ecdb..b1468f8 100644 --- a/hid.c +++ b/hid.c @@ -1,3 +1,7 @@ +#include "hid.h" + +#include "vec.h" + #include #include #include @@ -10,9 +14,6 @@ #include #include -#include "hid.h" -#include "vec.h" - // List of uniq of the currently known devices static Vec devices; // List of the new devices of a poll, static to keep the allocation alive @@ -59,7 +60,7 @@ void setup_device(PhysicalDevice *dev) { for (int i = 0; i < ABS_CNT; i++) dev->mapping.abs_indices[i] = -1; for (int i = 0; i < REL_CNT; i++) - dev->mapping.key_indices[i] = -1; + dev->mapping.rel_indices[i] = -1; for (int i = 0; i < KEY_CNT; i++) dev->mapping.key_indices[i] = -1; @@ -74,7 +75,7 @@ void setup_device(PhysicalDevice *dev) { if (i == EV_ABS) { struct input_absinfo abs; ioctl(dev->event, EVIOCGABS(j), &abs); - uint8_t index = dev->device_info.abs_count++; + uint16_t index = dev->device_info.abs_count++; dev->device_info.abs_id[index] = j; dev->device_info.abs_min[index] = abs.minimum; dev->device_info.abs_max[index] = abs.maximum; @@ -83,11 +84,11 @@ void setup_device(PhysicalDevice *dev) { dev->device_info.abs_res[index] = abs.resolution; dev->mapping.abs_indices[j] = index; } else if (i == EV_REL) { - uint8_t index = dev->device_info.rel_count++; + uint16_t index = dev->device_info.rel_count++; dev->device_info.rel_id[index] = j; dev->mapping.rel_indices[j] = index; } else if (i == EV_KEY) { - uint8_t index = dev->device_info.key_count++; + uint16_t index = dev->device_info.key_count++; dev->device_info.key_id[index] = j; dev->mapping.key_indices[j] = index; } @@ -153,10 +154,10 @@ PhysicalDevice get_device() { void return_device(PhysicalDevice *dev) { if (dev->name != NULL && dev->name != DEFAULT_NAME) { - printf("HID: Returning device '%s' (%012lx)\n", dev->name, dev->uniq); + printf("HID: Returning device '%s' (%012lx)\n", dev->name, dev->uniq); free(dev->name); } else { - printf("HID: Returning device %012lx\n", dev->uniq); + printf("HID: Returning device %012lx\n", dev->uniq); } close(dev->event); close(dev->hidraw); @@ -272,7 +273,7 @@ void poll_devices() { pthread_mutex_unlock(&devices_mutex); vec_push(&new_devices, &dev); - printf("HID: New device, %s (%s: %012lx)\n", name, input->d_name, dev.uniq); + printf("HID: New device, %s (%s: %012lx)\n", name, input->d_name, dev.uniq); continue; // close open file descriptor and continue @@ -311,7 +312,7 @@ void apply_controller_state(PhysicalDevice *dev, MessageControllerState *state) } void *hid_thread() { - printf("HID: start\n"); + printf("HID: start\n"); poll_devices_init(); while (1) { poll_devices(); diff --git a/hid.h b/hid.h index 69dae9c..348bd6e 100644 --- a/hid.h +++ b/hid.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef HID_H #define HID_H #include "net.h" @@ -8,9 +8,9 @@ typedef uint64_t uniq_t; typedef struct { - uint8_t abs_indices[ABS_CNT]; - uint8_t rel_indices[REL_CNT]; - uint8_t key_indices[KEY_CNT]; + uint16_t abs_indices[ABS_CNT]; + uint16_t rel_indices[REL_CNT]; + uint16_t key_indices[KEY_CNT]; } DeviceMap; typedef struct { diff --git a/main.c b/main.c index 5fa18d0..cb3d1a1 100644 --- a/main.c +++ b/main.c @@ -1,15 +1,16 @@ +#include "main.h" + +#include "client.h" +#include "hid.h" +#include "server.h" +#include "util.h" + #include #include #include #include #include -#include "client.h" -#include "hid.h" -#include "main.h" -#include "server.h" -#include "util.h" - const char *USAGE[] = { "jsfw client [address] [port]\n", "jsfw server [port]\n", diff --git a/main.h b/main.h index 31fbbd3..dd8b9cd 100644 --- a/main.h +++ b/main.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef MAIN_H #define MAIN_H diff --git a/net.c b/net.c index a170618..7ef8ed2 100644 --- a/net.c +++ b/net.c @@ -1,4 +1,5 @@ #include "net.h" + #include Message msg_device_info() { @@ -18,16 +19,17 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *dst) { uint8_t code_byte = buf[0]; MessageCode code = (MessageCode)code_byte; - uint8_t abs, rel, key; + uint16_t abs, rel, key, *buf16; switch (code) { case DeviceInfo: - if (len < 3) + if (len < 6) return -1; - abs = buf[1]; - rel = buf[2]; - key = buf[3]; - buf += 4; + buf16 = (uint16_t *)(buf + 1); + abs = buf16[0]; + rel = buf16[1]; + key = buf16[2]; + buf += 7; if (MSS_DEVICE_INFO(abs, rel, key) > len) return -1; @@ -38,33 +40,38 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *dst) { // SOA in c but serialized as AOS for (int i = 0; i < abs; i++) { - uint32_t *buf32 = (uint32_t *)(buf + 1); + uint32_t *buf32 = (uint32_t *)(buf + 2); - dst->device_info.abs_id[i] = buf[0]; + dst->device_info.abs_id[i] = *(uint16_t *)buf; dst->device_info.abs_min[i] = buf32[0]; dst->device_info.abs_max[i] = buf32[1]; dst->device_info.abs_fuzz[i] = buf32[2]; dst->device_info.abs_flat[i] = buf32[3]; dst->device_info.abs_res[i] = buf32[4]; - buf += 21; + buf += 22; } - for (int i = 0; i < rel; i++) - dst->device_info.rel_id[i] = *(buf++); + for (int i = 0; i < rel; i++) { + dst->device_info.rel_id[i] = *(uint16_t *)buf; + buf += 2; + } - for (int i = 0; i < key; i++) - dst->device_info.key_id[i] = *(buf++); + for (int i = 0; i < key; i++) { + dst->device_info.key_id[i] = *(uint16_t *)buf; + buf += 2; + } return 0; case DeviceReport: - if (len < 3) + if (len < 6) return -1; - abs = buf[1]; - rel = buf[2]; - key = buf[3]; - buf += 4; + buf16 = (uint16_t *)(buf + 1); + abs = buf16[0]; + rel = buf16[1]; + key = buf16[2]; + buf += 7; if (len < MSS_DEVICE_REPORT(abs, rel, key)) return -1; @@ -86,11 +93,6 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *dst) { for (int i = 0; i < key; i++) dst->device_report.key[i] = *(buf++); - return 0; - case DeviceDestroy: - if (len < MSS_DEVICE_DESTROY) - return -1; - dst->code = code; return 0; case ControllerState: if (len < MSS_CONTROLLER_STATE) @@ -115,7 +117,7 @@ int msg_serialize(uint8_t *buf, size_t len, Message *msg) { if (len-- == 0) return -1; - uint8_t abs, rel, key; + uint16_t abs, rel, key, *buf16; switch (msg->code) { case DeviceInfo: @@ -125,30 +127,36 @@ int msg_serialize(uint8_t *buf, size_t len, Message *msg) { if (len < MSS_DEVICE_INFO(abs, rel, key)) return -1; - buf[0] = (uint8_t)msg->code; - buf[1] = abs; - buf[2] = rel; - buf[3] = key; - buf += 4; + buf[0] = (uint8_t)msg->code; + buf16 = (uint16_t *)(buf + 1); + buf16[0] = abs; + buf16[1] = rel; + buf16[2] = key; + buf += 7; for (int i = 0; i < abs; i++) { - uint32_t *buf32 = (uint32_t *)(buf + 1); + uint32_t *buf32 = (uint32_t *)(buf + 2); + + *(uint16_t *)buf = msg->device_info.abs_id[i]; - buf[0] = msg->device_info.abs_id[i]; buf32[0] = msg->device_info.abs_min[i]; buf32[1] = msg->device_info.abs_max[i]; buf32[2] = msg->device_info.abs_fuzz[i]; buf32[3] = msg->device_info.abs_flat[i]; buf32[4] = msg->device_info.abs_res[i]; - buf += 21; + buf += 22; } - for (int i = 0; i < rel; i++) - *(buf++) = msg->device_info.rel_id[i]; + for (int i = 0; i < rel; i++) { + *(uint16_t *)buf = msg->device_info.rel_id[i]; + buf += 2; + } - for (int i = 0; i < key; i++) - *(buf++) = msg->device_info.key_id[i]; + for (int i = 0; i < key; i++) { + *(uint16_t *)buf = msg->device_info.key_id[i]; + buf += 2; + } return MSS_DEVICE_INFO(abs, rel, key) + 1; case DeviceReport: @@ -157,11 +165,13 @@ int msg_serialize(uint8_t *buf, size_t len, Message *msg) { key = msg->device_report.key_count; if (len < MSS_DEVICE_REPORT(abs, rel, key)) return -1; - buf[0] = (uint8_t)msg->code; - buf[1] = abs; - buf[2] = rel; - buf[3] = key; - buf += 4; + + buf[0] = (uint8_t)msg->code; + buf16 = (uint16_t *)(buf + 1); + buf16[0] = abs; + buf16[1] = rel; + buf16[2] = key; + buf += 7; for (int i = 0; i < abs; i++) { *(uint32_t *)buf = msg->device_report.abs[i]; @@ -177,12 +187,6 @@ int msg_serialize(uint8_t *buf, size_t len, Message *msg) { *(buf++) = msg->device_report.key[i]; return MSS_DEVICE_REPORT(abs, rel, key) + 1; - case DeviceDestroy: - if (len < MSS_DEVICE_DESTROY) - return -1; - - buf[0] = (uint8_t)msg->code; - return MSS_DEVICE_DESTROY + 1; case ControllerState: if (len < MSS_CONTROLLER_STATE) return -1; diff --git a/net.h b/net.h index dafd98e..2ebae6b 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef NET_H #define NET_H #include @@ -12,46 +12,40 @@ typedef enum { ControllerState = 4, } MessageCode; -// TODO: replace counts by uint16_t typedef struct { MessageCode code; - uint8_t abs_count; - uint8_t rel_count; - uint8_t key_count; + uint16_t abs_count; + uint16_t rel_count; + uint16_t key_count; - uint8_t abs_id[ABS_CNT]; + uint16_t abs_id[ABS_CNT]; uint32_t abs_min[ABS_CNT]; uint32_t abs_max[ABS_CNT]; uint32_t abs_fuzz[ABS_CNT]; uint32_t abs_flat[ABS_CNT]; uint32_t abs_res[ABS_CNT]; - uint8_t rel_id[REL_CNT]; + uint16_t rel_id[REL_CNT]; - uint8_t key_id[KEY_CNT]; + uint16_t key_id[KEY_CNT]; } MessageDeviceInfo; -#define MSS_DEVICE_INFO(abs, rel, key) (3 + abs * 21 + rel * 1 + key * 1) +#define MSS_DEVICE_INFO(abs, rel, key) (6 + abs * 22 + rel * 2 + key * 2) // MSS -> Message Serialized Size: // Size of the data of the message when serialized (no alignment / padding) typedef struct { MessageCode code; - uint8_t abs_count; - uint8_t rel_count; - uint8_t key_count; + uint16_t abs_count; + uint16_t rel_count; + uint16_t key_count; uint32_t abs[ABS_CNT]; uint32_t rel[REL_CNT]; uint8_t key[KEY_CNT]; } MessageDeviceReport; -#define MSS_DEVICE_REPORT(abs, rel, key) (3 + abs * 4 + rel * 4 + key * 1) - -typedef struct { - MessageCode code; -} MessageDeviceDestroy; -#define MSS_DEVICE_DESTROY 0 +#define MSS_DEVICE_REPORT(abs, rel, key) (6 + abs * 4 + rel * 4 + key * 1) typedef struct { MessageCode code; @@ -68,7 +62,6 @@ typedef union { MessageCode code; MessageDeviceInfo device_info; MessageDeviceReport device_report; - MessageDeviceDestroy device_destroy; MessageControllerState controller_state; } Message; diff --git a/server.c b/server.c index 4ccd0ba..d6b0e24 100644 --- a/server.c +++ b/server.c @@ -1,3 +1,7 @@ +#include "hid.h" +#include "net.h" +#include "util.h" + #include #include #include @@ -11,10 +15,6 @@ #include #include -#include "hid.h" -#include "net.h" -#include "util.h" - struct Connection { int socket; uint32_t id; @@ -62,15 +62,28 @@ void *server_handle_conn(void *args_) { report.rel_count = dev.device_info.rel_count; report.key_count = dev.device_info.key_count; + char *closing_message = ""; + while (1) { int rc = poll(pfds, 2, -1); - if (rc < 0) // error (connection closed) + if (rc < 0) { // error (connection closed) + closing_message = "Poll error"; goto conn_end; + } + + // Shutdown connection if we lost the peer + if (socket_poll->revents & POLLHUP || socket_poll->revents & POLLERR) { + closing_message = "Lost peer"; + goto conn_end; + } if (socket_poll->revents & POLLIN) { int len = recv(args->socket, buf, 2048, 0); - if (len <= 0) + + if (len <= 0) { + closing_message = "Lost peer"; goto conn_end; + } Message msg; if (msg_deserialize(buf, len, &msg) == 0) { @@ -85,11 +98,23 @@ void *server_handle_conn(void *args_) { printf("CONN(%d): Couldn't parse message.\n", args->id); } } + + // Shutdown connection if we lost the device + if (event_poll->revents & POLLHUP || event_poll->revents & POLLERR) { + closing_message = "Lost device"; + goto conn_end; + } + if (event_poll->revents & POLLIN) { struct input_event event; - int len = read(dev.event, &event, sizeof(struct input_event)); - if (len <= 0) + + int len = read(dev.event, &event, sizeof(struct input_event)); + + if (len <= 0) { + closing_message = "Lost device"; goto conn_end; + } + if (len < sizeof(struct input_event)) { printf("CONN(%d): error reading event\n", args->id); continue; @@ -129,7 +154,6 @@ void *server_handle_conn(void *args_) { printf("CONN(%d): Invalid key\n", args->id); continue; }; - report.key[index] = !!event.value; } } @@ -137,14 +161,14 @@ void *server_handle_conn(void *args_) { conn_end: shutdown(args->socket, SHUT_RDWR); - printf("CONN(%u): connection closed\n", args->id); + printf("CONN(%u): connection closed (%s)\n", args->id, closing_message); return_device(&dev); free(args); return NULL; } void server_run(uint16_t port) { - printf("SERVER: start\n"); + printf("SERVER: start\n"); int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) @@ -170,7 +194,7 @@ void server_run(uint16_t port) { conn.socket = accept(sock, &con_addr, &con_len); if (conn.socket >= 0) { - printf("SERVER: got connection\n"); + printf("SERVER: got connection\n"); conn.id = ids++; diff --git a/server.h b/server.h index bdcbf07..bfe0f89 100644 --- a/server.h +++ b/server.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef SERVER_H #define SERVER_H #include diff --git a/util.c b/util.c index 0624439..57fbaec 100644 --- a/util.c +++ b/util.c @@ -1,9 +1,9 @@ +#include "util.h" + #include #include #include -#include "util.h" - #ifndef __has_builtin #define __has_builtin(_) 0 #endif diff --git a/util.h b/util.h index ecb8a93..9fc1f62 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef UTIL_H #define UTIL_H diff --git a/vec.c b/vec.c index 43daa6c..a2ee640 100644 --- a/vec.c +++ b/vec.c @@ -1,4 +1,5 @@ #include "vec.h" + #include #include #include diff --git a/vec.h b/vec.h index af08a0b..fe0b90d 100644 --- a/vec.h +++ b/vec.h @@ -1,4 +1,4 @@ -// vi: set ft=c +// vi:ft=c #ifndef VEC_H #define VEC_H #include