diff --git a/README.md b/README.md index 6db19c5..91c2b99 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,13 @@ and a client with this one: ```json { - "controllers": [ + "slots": [ { - "tag": ["Controller"] + "controllers": [ + { + "tag": "Controller" + } + ] } ] } @@ -104,17 +108,24 @@ The client configuration specifies what devices the client wants as well as unde ```js // Any property can be ommitted, unless specified otherwise // The values listed here are examples +// Comments are here to document things, they are not allowed in the actual config { - "controllers": [ + // (required) The slots the client has + "slots": [ { - // (required) Accepted tags of the device to request - "tag": ["Joystick"], - // (default: 6969) Vendor code for the virtual device, expects a 4 long hex string - "vendor": "dead", - // (default: 0420) Product code for the virtual device, expects a 4 long hex string - "product": "beef", - // (default: "JSFW Virtual Device") Name for the virtual device - "name": "Emanuel" + // (required) The controllers that are accepted in that slot + "controllers": [ + { + // (required) Accepted tags of the device to request + "tag": ["Joystick"], + // (default: 6969) Vendor code for the virtual device, expects a 4 long hex string + "vendor": "dead", + // (default: 0420) Product code for the virtual device, expects a 4 long hex string + "product": "beef", + // (default: "JSFW Virtual Device") Name for the virtual device + "name": "Emanuel" + } + ] } ], // (default: "/tmp/jsfw_fifo") Path to the fifo for hidraw @@ -130,7 +141,7 @@ Additionaly messages can be sent to the client's fifo to change the led colors ( // Any property can be ommitted, unless specified otherwise // The values listed here are examples { - // (default: 0) Index of the device to send the state to, this is the index in the client configuration controllers list + // (default: 0) Index of the slot to send the state to, this is the index in the client configuration controllers list "index": 1, // (default: [0, 0]) Setting for the rumble, values are in range 0-255 first element is small rumble, second is big "rumble": [255, 0], diff --git a/client.c b/client.c index d053d85..3f47ebb 100644 --- a/client.c +++ b/client.c @@ -72,7 +72,7 @@ static const JSONAdapter ControllerStateAdapter = { }; static const JSONPropertyAdapter ControllerAdapterProps[] = { - {".tag[]", &StringAdapter, offsetof(ClientController, tags), default_to_null, NULL }, + {".tag", &StringAdapter, offsetof(ClientController, tag), default_to_null, NULL }, {".vendor", &StringAdapter, offsetof(ClientController, device_vendor), default_vendor, tsf_hex_to_i32}, {".product", &StringAdapter, offsetof(ClientController, device_product), default_product, tsf_hex_to_i32}, {".name", &StringAdapter, offsetof(ClientController, device_name), default_name, NULL }, @@ -83,10 +83,19 @@ static const JSONAdapter ControllerAdapter = { .size = sizeof(ClientController), }; +static const JSONPropertyAdapter SlotAdapterProps[] = { + {".controllers[]", &ControllerAdapter, offsetof(ClientSlot, controllers), default_to_null, NULL}, +}; +static const JSONAdapter SlotAdapter = { + .props = SlotAdapterProps, + .prop_count = sizeof(SlotAdapterProps) / sizeof(JSONPropertyAdapter), + .size = sizeof(ClientSlot), +}; + static const JSONPropertyAdapter ClientConfigAdapterProps[] = { - {".controllers[]", &ControllerAdapter, offsetof(ClientConfig, controllers), default_to_null, NULL }, - {".fifo_path", &StringAdapter, offsetof(ClientConfig, fifo_path), default_fifo_path, NULL }, - {".retry_delay", &NumberAdapter, offsetof(ClientConfig, retry_delay), default_retry_delay, tsf_numsec_to_timespec} + {".slots[]", &SlotAdapter, offsetof(ClientConfig, slots), default_to_null, NULL }, + {".fifo_path", &StringAdapter, offsetof(ClientConfig, fifo_path), default_fifo_path, NULL }, + {".retry_delay", &NumberAdapter, offsetof(ClientConfig, retry_delay), default_retry_delay, tsf_numsec_to_timespec} }; static const JSONAdapter ConfigAdapter = { .props = ClientConfigAdapterProps, @@ -99,23 +108,23 @@ static void print_config() { printf("CLIENT: Config\n"); printf(" fifo_path: %s\n", config.fifo_path); printf(" retry_delay: %fs\n", timespec_to_double(&config.retry_delay)); - printf(" controllers: \n"); - for (size_t i = 0; i < config.controller_count; i++) { - ClientController *ctr = &config.controllers[i]; - printf(" - tags: ['%s'", ctr->tags[0]); - for (size_t j = 1; j < ctr->tag_count; j++) { - printf(", '%s'", ctr->tags[j]); + printf(" slots: \n"); + for (size_t i = 0; i < config.slot_count; i++) { + ClientSlot *slot = &config.slots[i]; + printf(" - controllers:\n"); + for (size_t j = 0; j < slot->controller_count; j++) { + ClientController *ctr = &slot->controllers[j]; + printf(" - tag: '%s'\n", ctr->tag); + printf(" name: %s\n", ctr->device_name); + printf(" vendor: %04x\n", ctr->device_vendor); + printf(" product: %04x\n", ctr->device_product); } - printf("]\n"); - printf(" name: %s\n", ctr->device_name); - printf(" vendor: %04x\n", ctr->device_vendor); - printf(" product: %04x\n", ctr->device_product); } printf("\n"); } void destroy_devices(void) { - for (int i = 0; i < config.controller_count; i++) { + for (int i = 0; i < config.slot_count; i++) { int fd = *(int *)vec_get(&devices_fd, i); MessageDeviceInfo *info = vec_get(&devices_info, i); @@ -135,14 +144,14 @@ bool device_exists(int index) { return info->code == DeviceInfo; } -void device_destroy(int index) { - if (index >= devices_info.len) { +void device_destroy(int slot) { + if (slot >= devices_info.len) { return; } - int fd = *(int *)vec_get(&devices_fd, index); + int fd = *(int *)vec_get(&devices_fd, slot); - MessageDeviceInfo *info = vec_get(&devices_info, index); + MessageDeviceInfo *info = vec_get(&devices_info, slot); if (info->code == DeviceInfo) { ioctl(fd, UI_DEV_DESTROY); @@ -151,14 +160,14 @@ void device_destroy(int index) { } void device_init(MessageDeviceInfo *dev) { - if (dev->index >= devices_info.len) { + if (dev->slot >= devices_info.len) { printf("CLIENT: Got wrong device index\n"); return; } - device_destroy(dev->index); + device_destroy(dev->slot); - int fd = *(int *)vec_get(&devices_fd, dev->index); + int fd = *(int *)vec_get(&devices_fd, dev->slot); // Abs if (dev->abs_count > 0) { @@ -193,7 +202,7 @@ void device_init(MessageDeviceInfo *dev) { } } - ClientController *ctr = &config.controllers[dev->index]; + ClientController *ctr = &config.slots[dev->slot].controllers[dev->index]; struct uinput_setup setup = {0}; @@ -206,10 +215,10 @@ void device_init(MessageDeviceInfo *dev) { ioctl(fd, UI_DEV_SETUP, &setup); ioctl(fd, UI_DEV_CREATE); - MessageDeviceInfo *dst = vec_get(&devices_info, dev->index); + MessageDeviceInfo *dst = vec_get(&devices_info, dev->slot); memcpy(dst, dev, sizeof(MessageDeviceInfo)); - printf("CLIENT: Got device [%d]: '%s' (abs: %d, rel: %d, key: %d)\n", dev->index, ctr->device_name, dev->abs_count, + printf("CLIENT: Got device [%d]: '%s' (abs: %d, rel: %d, key: %d)\n", dev->slot, ctr->device_name, dev->abs_count, dev->rel_count, dev->key_count); } @@ -231,12 +240,12 @@ bool device_emit(int index, uint16_t type, uint16_t id, uint32_t value) { // Update device with report void device_handle_report(MessageDeviceReport *report) { - if (!device_exists(report->index)) { - printf("CLIENT: [%d] Got report before device info\n", report->index); + if (!device_exists(report->slot)) { + printf("CLIENT: [%d] Got report before device info\n", report->slot); return; } - MessageDeviceInfo *info = vec_get(&devices_info, report->index); + MessageDeviceInfo *info = vec_get(&devices_info, report->slot); if (report->abs_count != info->abs_count || report->rel_count != info->rel_count || report->key_count != info->key_count) { printf("CLIENT: Report doesn't match with device info\n"); @@ -244,25 +253,25 @@ void device_handle_report(MessageDeviceReport *report) { } for (int i = 0; i < report->abs_count; i++) { - if (device_emit(report->index, EV_ABS, info->abs_id[i], report->abs[i]) != 0) { + if (device_emit(report->slot, EV_ABS, 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(report->index, EV_REL, info->rel_id[i], report->rel[i]) != 0) { + if (device_emit(report->slot, EV_REL, 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(report->index, EV_KEY, info->key_id[i], (uint32_t)(!report->key[i]) - 1) != 0) { + if (device_emit(report->slot, EV_KEY, info->key_id[i], (uint32_t)(!report->key[i]) - 1) != 0) { printf("CLIENT: Error writing key event to uinput\n"); } } // Reports are sent by the server every time the server receives an EV_SYN from the physical device, so we // send one when we receive the report to match - device_emit(report->index, EV_SYN, 0, 0); + device_emit(report->slot, EV_SYN, 0, 0); } void setup_devices(void) { @@ -272,7 +281,7 @@ void setup_devices(void) { MessageDeviceInfo no_info = {0}; no_info.code = NoMessage; - for (int i = 0; i < config.controller_count; i++) { + for (int i = 0; i < config.slot_count; i++) { int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); if (fd < 0) { perror("CLIENT: Can't open /dev/uinput, aborting now"); @@ -371,19 +380,19 @@ void setup_server(char *address, uint16_t port) { } void build_device_request(void) { - TagList * reqs = malloc(config.controller_count * sizeof(TagList *)); - for (int i = 0; i < config.controller_count; i++) { - TagList * req = &reqs[i]; - req->count = config.controllers[i].tag_count; - req->tags = malloc(req->count * sizeof(char *)); + TagList *reqs = malloc(config.slot_count * sizeof(TagList)); + for (int i = 0; i < config.slot_count; i++) { + TagList *req = &reqs[i]; + req->count = config.slots[i].controller_count; + req->tags = malloc(req->count * sizeof(char *)); for (int j = 0; j < req->count; j++) { - req->tags[j] = config.controllers[i].tags[j]; + req->tags[j] = config.slots[i].controllers[j].tag; } } device_request.code = Request; - device_request.request_count = config.controller_count; + device_request.request_count = config.slot_count; device_request.requests = reqs; } @@ -490,12 +499,11 @@ void client_run(char *address, uint16_t port, char *config_path) { recv(sock, buf, msg_len, 0); if (message.code == DeviceInfo) { - if (device_exists(message.device_info.index)) { + if (device_exists(message.device_info.slot)) { printf("CLIENT: Got more than one device info for same device\n"); } device_init((MessageDeviceInfo *)&message); - printf("CLIENT: Got device %d\n", message.device_info.index); } else if (message.code == DeviceReport) { device_handle_report((MessageDeviceReport *)&message); } else if (message.code == DeviceDestroy) { diff --git a/client.h b/client.h index 437795f..26f92e6 100644 --- a/client.h +++ b/client.h @@ -7,8 +7,7 @@ void client_run(char *address, uint16_t port, char *config_path); typedef struct { - char **tags; - size_t tag_count; + char *tag; int32_t device_vendor; int32_t device_product; char *device_name; @@ -17,6 +16,11 @@ typedef struct { typedef struct { ClientController *controllers; size_t controller_count; +} ClientSlot; + +typedef struct { + ClientSlot *slots; + size_t slot_count; char *fifo_path; struct timespec retry_delay; diff --git a/hid.c b/hid.c index d7d306b..6d10aea 100644 --- a/hid.c +++ b/hid.c @@ -167,49 +167,55 @@ bool filter_event(int fd, char *event, ControllerFilter *filter, uniq_t uniq) { // Initialize vectors for polling void poll_devices_init(void) { - known_devices = vec_of(Controller); - cloneable_devices = vec_of(Controller *); - available_devices = vec_of(Controller *); + known_devices = vec_of(uint64_t); + cloneable_devices = vec_of(Controller); + available_devices = vec_of(Controller); } -// Check if tag match any of the tags specified in the tags array (of length tag_count) -bool match_tags(char *tag, char **tags, size_t tag_count) { +// Find index of tag that matches any of the tags specified in the tags array (of length tag_count), returns -1 otherwise +static int match_tags(char *tag, char **tags, size_t tag_count) { for (int i = 0; i < tag_count; i++) { if (strcmp(tag, tags[i]) == 0) { - return true; + return i; } } - return false; + return -1; } // Block to get a device, this is thread safe // stop: additional condition to check before doing anything, // if the condition is ever found to be true the function will return immediately with a NULL pointer. -Controller *get_device(char **tags, size_t tag_count, bool *stop) { +bool get_device(char **tags, size_t tag_count, bool *stop, Controller *res, uint8_t *ref_index) { // Check if we can get one right away pthread_mutex_lock(&devices_mutex); while (1) { if (*stop) { pthread_mutex_unlock(&devices_mutex); - return NULL; + return false; } for (int i = 0; i < available_devices.len; i++) { - Controller *c = *(Controller **)vec_get(&available_devices, i); - if (match_tags(c->ctr.tag, tags, tag_count)) { + Controller *c = vec_get(&available_devices, i); + int index = match_tags(c->ctr.tag, tags, tag_count); + if (index >= 0) { + *ref_index = index; + *res = *c; vec_remove(&available_devices, i, NULL); pthread_mutex_unlock(&devices_mutex); - return c; + return true; } } for (int i = 0; i < cloneable_devices.len; i++) { - Controller *c = *(Controller **)vec_get(&cloneable_devices, i); - if (match_tags(c->ctr.tag, tags, tag_count)) { + Controller *c = vec_get(&cloneable_devices, i); + int index = match_tags(c->ctr.tag, tags, tag_count); + if (index >= 0) { + *ref_index = index; + *res = *c; pthread_mutex_unlock(&devices_mutex); - return c; + return true; } } @@ -226,7 +232,7 @@ void return_device(Controller *c) { } pthread_mutex_lock(&devices_mutex); - vec_push(&available_devices, &c); + vec_push(&available_devices, c); // Signal that there are new devices pthread_cond_broadcast(&devices_cond); pthread_mutex_unlock(&devices_mutex); @@ -234,26 +240,25 @@ void return_device(Controller *c) { // Forget about a broken device. This invalidates the reference to the controller void forget_device(Controller *c) { + pthread_mutex_lock(&known_devices_mutex); // If controller is cloneable we need to remove it from the cloneable list if (c->ctr.duplicate) { - pthread_mutex_lock(&devices_mutex); for (int i = 0; i < cloneable_devices.len; i++) { Controller *d = *(Controller **)vec_get(&cloneable_devices, i); - if (d->dev.uniq == c->dev.uniq) { + if (d->dev.id == c->dev.id) { vec_remove(&cloneable_devices, i, NULL); break; } } - pthread_mutex_unlock(&devices_mutex); } // Free the name if it was allocated if (c->dev.name != NULL && c->dev.name != DEVICE_DEFAULT_NAME) { - printf("HID: Forgetting device '%s' (%016lx)\n", c->dev.name, c->dev.uniq); + printf("HID: Forgetting device '%s' (%lu)\n", c->dev.name, c->dev.id); free(c->dev.name); } else { - printf("HID: Forgetting device %016lx\n", c->dev.uniq); + printf("HID: Forgetting device %lu\n", c->dev.id); } // try to close the file descriptor, they may be already closed if the device was unpugged. @@ -261,10 +266,9 @@ void forget_device(Controller *c) { close(c->dev.hidraw); // Safely remove device from the known device list - pthread_mutex_lock(&known_devices_mutex); for (int i = 0; i < known_devices.len; i++) { - Controller *d = vec_get(&known_devices, i); - if (d->dev.uniq == c->dev.uniq) { + uint64_t *id = vec_get(&known_devices, i); + if (*id == c->dev.id) { vec_remove(&known_devices, i, NULL); break; } @@ -272,6 +276,8 @@ void forget_device(Controller *c) { pthread_mutex_unlock(&known_devices_mutex); } +uint64_t parse_event_name(const char *event) { return atol(event + 5); } + // Find all available devices and pick up on new ones void poll_devices(void) { // loop over all entries of /sys/class/input @@ -287,6 +293,7 @@ void poll_devices(void) { PhysicalDevice dev; dev.hidraw = -1; dev.uniq = 0; + dev.id = parse_event_name(input->d_name); // Open /dev/input/eventXX { @@ -340,21 +347,14 @@ void poll_devices(void) { } } - // Get the id - { - struct input_id id; - ioctl(dev.event, EVIOCGID, &id); - dev.id = *(uint64_t *)&id; - } - // Check if we already know of this device { found = false; pthread_mutex_lock(&known_devices_mutex); for (int i = 0; i < known_devices.len; i++) { - Controller *c = vec_get(&known_devices, i); - if (c->dev.uniq == dev.uniq) { + uint64_t *id = vec_get(&known_devices, i); + if (*id == dev.id) { found = true; break; } @@ -415,25 +415,20 @@ void poll_devices(void) { Controller c = {.dev = dev, .ctr = *ctr}; pthread_mutex_lock(&known_devices_mutex); - // Index of the device in known_devices - int index = known_devices.len; - vec_push(&known_devices, &c); + vec_push(&known_devices, &c.dev.id); pthread_mutex_unlock(&known_devices_mutex); - // Pointer to the device in known_devices - Controller *p = vec_get(&known_devices, index); - - printf("HID: New device, %s [%s] (%s: %016lx)\n", name, ctr->tag, input->d_name, dev.uniq); + printf("HID: New device, %s [%s] (%s: %lu)\n", name, ctr->tag, input->d_name, dev.id); if (ctr->duplicate) { pthread_mutex_lock(&devices_mutex); - vec_push(&cloneable_devices, &p); + vec_push(&cloneable_devices, &c); // Signal that there are new cloneable devices pthread_cond_broadcast(&devices_cond); pthread_mutex_unlock(&devices_mutex); } else { pthread_mutex_lock(&devices_mutex); - vec_push(&available_devices, &p); + vec_push(&available_devices, &c); // Signal that there are new devices pthread_cond_broadcast(&devices_cond); pthread_mutex_unlock(&devices_mutex); @@ -452,11 +447,11 @@ void poll_devices(void) { // "Execute" a MessageControllerState: set the led color, rumble and flash using the hidraw interface (Dualshock 4 only) void apply_controller_state(Controller *c, MessageControllerState *state) { if (c->ctr.ps4_hidraw && c->dev.hidraw < 0) { - printf("HID: Trying to apply controller state on incompatible device (%016lx)\n", c->dev.uniq); + printf("HID: Trying to apply controller state on incompatible device (%lu)\n", c->dev.id); return; } - printf("HID: (%016lx) Controller state: #%02x%02x%02x flash: (%d, %d) rumble: (%d, %d)\n", c->dev.uniq, state->led[0], + printf("HID: (%lu) Controller state: #%02x%02x%02x flash: (%d, %d) rumble: (%d, %d)\n", c->dev.id, state->led[0], state->led[1], state->led[2], state->flash_on, state->flash_off, state->small_rumble, state->big_rumble); uint8_t buf[32] = {0x05, 0xff, 0x00, 0x00}; diff --git a/hid.h b/hid.h index 424caf2..daf6191 100644 --- a/hid.h +++ b/hid.h @@ -9,7 +9,7 @@ #include #include -// Unique identifier for devices (provided by linux), May be the mac address +// Unique identifier for devices (provided by linux) typedef uint64_t uniq_t; // Mapping to go from index to id of events @@ -38,10 +38,10 @@ typedef struct { ServerConfigController ctr; } Controller; -void *hid_thread(void *arg); -void return_device(Controller *c); -void forget_device(Controller *c); -Controller *get_device(char **tags, size_t tag_count, bool *stop); -void apply_controller_state(Controller *c, MessageControllerState *state); +void *hid_thread(void *arg); +void return_device(Controller *c); +void forget_device(Controller *c); +bool get_device(char **tags, size_t tag_count, bool *stop, Controller *res, uint8_t *index); +void apply_controller_state(Controller *c, MessageControllerState *state); #endif diff --git a/net.c b/net.c index ca78b92..00f8a6e 100644 --- a/net.c +++ b/net.c @@ -30,23 +30,26 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *restrict dst) { MessageCode code = (MessageCode)code_byte; uint32_t size = 0; - uint16_t abs, rel, key, index, *buf16; + uint16_t abs, rel, key, *buf16; + uint8_t index, slot; switch (code) { case DeviceInfo: if (len < 7) return -1; - // buf + 2: a byte for code and a byte for padding - buf16 = (uint16_t *)(buf + 2); - index = buf16[0]; - abs = buf16[1]; - rel = buf16[2]; - key = buf16[3]; + slot = buf[2]; + index = buf[3]; + // buf + 4: a byte for, code, padding, slot, index + buf16 = (uint16_t *)(buf + 4); + abs = buf16[0]; + rel = buf16[1]; + key = buf16[2]; buf += 12; if (MSS_DEVICE_INFO(abs, rel, key) > len) return -1; dst->device_info.code = code; + dst->device_info.slot = slot; dst->device_info.index = index; dst->device_info.abs_count = abs; dst->device_info.rel_count = rel; @@ -83,17 +86,19 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *restrict dst) { if (len < 7) return -1; - // buf + 2: a byte for code and a byte of padding - buf16 = (uint16_t *)(buf + 2); - index = buf16[0]; - abs = buf16[1]; - rel = buf16[2]; - key = buf16[3]; + slot = buf[2]; + index = buf[3]; + // buf + 4: a byte for, code, padding, slot and index + buf16 = (uint16_t *)(buf + 4); + abs = buf16[0]; + rel = buf16[1]; + key = buf16[2]; buf += 12; if (len < MSS_DEVICE_REPORT(abs, rel, key)) return -1; dst->device_report.code = code; + dst->device_report.slot = slot; dst->device_report.index = index; dst->device_report.abs_count = abs; dst->device_report.rel_count = rel; @@ -198,16 +203,19 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message *restrict dst) { return -1; } - if (size + MAGIC_SIZE > len + 1) { + if (align_m(size) + MAGIC_SIZE > len + 1) { return -1; } - if (*(MAGIC_TYPE *)buf != MAGIC_END) { + // WARN: This is technically bad, but should be ok nonetheless + MAGIC_TYPE *mbuf = (MAGIC_TYPE *)align_m((uintptr_t)buf); + + if (*mbuf != MAGIC_END) { printf("NET: Magic not found\n"); return -1; } - return size + 2 * MAGIC_SIZE; + return align_m(size) + 2 * MAGIC_SIZE; } // Serialize the message msg in buf, buf must be at least 4 aligned. Returns -1 on error (buf not big enough); @@ -231,15 +239,15 @@ int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg) { if (len < MSS_DEVICE_INFO(abs, rel, key)) return -1; - // We begin 4 aligned buf[0] = (uint8_t)msg->code; - // buf + 2: a byte for code and a byte for padding - buf16 = (uint16_t *)(buf + 2); - // 2 aligned here - buf16[0] = msg->device_info.index; - buf16[1] = abs; - buf16[2] = rel; - buf16[3] = key; + // 1 byte of padding + buf[2] = (uint8_t)msg->device_info.slot; + buf[3] = (uint8_t)msg->device_info.index; + // buf + 4: a byte for, code, padding, slot, index + buf16 = (uint16_t *)(buf + 4); + buf16[0] = abs; + buf16[1] = rel; + buf16[2] = key; buf += 12; // Back to 4 aligned @@ -278,12 +286,14 @@ int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg) { return -1; buf[0] = (uint8_t)msg->code; - // buf + 2: a byte for code and a byte for padding - buf16 = (uint16_t *)(buf + 2); - buf16[0] = msg->device_report.index; - buf16[1] = abs; - buf16[2] = rel; - buf16[3] = key; + // 1 byte of padding + buf[2] = msg->device_report.slot; + buf[3] = msg->device_report.index; + // buf + 4: a byte for, code, padding, slot and index + buf16 = (uint16_t *)(buf + 4); + buf16[0] = abs; + buf16[1] = rel; + buf16[2] = key; buf += 12; // We're 4 aligned already for (int i = 0; i < abs; i++) { @@ -340,9 +350,7 @@ int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg) { buf += 2; for (int j = 0; j < tag_count; j++) { - printf("about to strlen\n"); int str_len = strlen(tags[j]); - printf("len : %i\n", str_len); int byte_len = align_2(str_len); expected_len += 2 + byte_len; @@ -376,13 +384,15 @@ int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg) { return -1; } - if (size + MAGIC_SIZE > len) { + if (align_m(size) + MAGIC_SIZE > len) { return -1; } - *(MAGIC_TYPE *)buf = MAGIC_END; + MAGIC_TYPE *mbuf = (MAGIC_TYPE *)align_m((uintptr_t)buf); - return size + MAGIC_SIZE * 2; + *mbuf = MAGIC_END; + + return align_m(size) + MAGIC_SIZE * 2; } void msg_free(Message *msg) { diff --git a/net.h b/net.h index 3088d18..1ae50ce 100644 --- a/net.h +++ b/net.h @@ -11,6 +11,8 @@ #define MAGIC_SIZE sizeof(MAGIC_TYPE) static const MAGIC_TYPE MAGIC_BEG = 0xDEADCAFE; static const MAGIC_TYPE MAGIC_END = 0xCAFEDEAD; +// Align n to the next MAGIC boundary +static inline size_t align_m(uintptr_t n) { return (((n - 1) >> 2) + 1) << 2; } typedef enum { NoMessage = 0, @@ -26,7 +28,8 @@ typedef struct { MessageCode code; // + 1 byte of padding - uint16_t index; + uint8_t slot; + uint8_t index; uint16_t abs_count; uint16_t rel_count; @@ -52,7 +55,9 @@ typedef struct { typedef struct { MessageCode code; // + 1 byte of padding - uint16_t index; + + uint8_t slot; + uint8_t index; uint16_t abs_count; uint16_t rel_count; diff --git a/server.c b/server.c index c3d4af1..de58dd9 100644 --- a/server.c +++ b/server.c @@ -123,6 +123,7 @@ void device_thread_exit(int _sig) { Controller *ctr = *args->controller; if (ctr != NULL) { return_device(ctr); + free(ctr); } for (int i = 0; i < args->tag_count; i++) { @@ -146,16 +147,22 @@ void *device_thread(void *args_) { MessageDeviceInfo dev_info; while (true) { + if (*args->controller != NULL) { + free(*args->controller); + } + *args->controller = NULL; - Controller *ctr = get_device(args->tags, args->tag_count, &args->conn->closed); - if (ctr == NULL) { + uint8_t controller_index; + Controller *ctr = malloc(sizeof(Controller)); + if (!get_device(args->tags, args->tag_count, &args->conn->closed, ctr, &controller_index)) { break; } *args->controller = ctr; dev_info = ctr->dev.device_info; - dev_info.index = args->index; + dev_info.slot = args->index; + dev_info.index = controller_index; - printf("CONN(%d): [%d] Found suitable [%s] device: '%s' (%016lx)\n", args->conn->id, args->index, ctr->ctr.tag, + printf("CONN(%d): [%d] Found suitable [%s] device: '%s' (%lu)\n", args->conn->id, args->index, ctr->ctr.tag, ctr->dev.name, ctr->dev.id); // Send over device info @@ -173,7 +180,8 @@ void *device_thread(void *args_) { report.abs_count = ctr->dev.device_info.abs_count; report.rel_count = ctr->dev.device_info.rel_count; report.key_count = ctr->dev.device_info.key_count; - report.index = args->index; + report.slot = args->index; + report.index = controller_index; while (true) { struct input_event event;