split up application in two different sub-applications
This commit is contained in:
parent
7e91e73327
commit
00fb3a02e3
20 changed files with 441 additions and 210 deletions
|
|
@ -9,33 +9,46 @@ project(
|
||||||
VERSION 1.0
|
VERSION 1.0
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
set(EXECUTABLE_NAME "rogue-enemy")
|
set(ROGUE_EXECUTABLE_NAME "rogue-enemy")
|
||||||
|
set(STRAY_EXECUTABLE_NAME "stray-ally")
|
||||||
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
# Adding something we can run - Output name matches target name
|
add_executable(${ROGUE_EXECUTABLE_NAME}
|
||||||
add_executable(${EXECUTABLE_NAME}
|
|
||||||
dev_evdev.c
|
dev_evdev.c
|
||||||
dev_iio.c
|
dev_iio.c
|
||||||
dev_hidraw.c
|
dev_hidraw.c
|
||||||
dev_in.c
|
dev_in.c
|
||||||
dev_out.c
|
|
||||||
main.c
|
main.c
|
||||||
settings.c
|
settings.c
|
||||||
virt_ds4.c
|
|
||||||
virt_ds5.c
|
|
||||||
devices_status.c
|
|
||||||
rog_ally.c
|
rog_ally.c
|
||||||
legion_go.c
|
legion_go.c
|
||||||
xbox360.c
|
xbox360.c
|
||||||
rogue_enemy.c
|
rogue_enemy.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${EXECUTABLE_NAME} PROPERTY C_STANDARD 17)
|
add_executable(${STRAY_EXECUTABLE_NAME}
|
||||||
|
dev_out.c
|
||||||
|
stray_ally.c
|
||||||
|
settings.c
|
||||||
|
virt_ds4.c
|
||||||
|
virt_ds5.c
|
||||||
|
devices_status.c
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(${EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm)
|
set_property(TARGET ${ROGUE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17)
|
||||||
|
|
||||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C)
|
target_link_libraries(${ROGUE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm)
|
||||||
|
|
||||||
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)
|
set_target_properties(${ROGUE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C)
|
||||||
|
|
||||||
|
install(TARGETS ${ROGUE_EXECUTABLE_NAME} DESTINATION bin)
|
||||||
|
|
||||||
|
set_property(TARGET ${STRAY_EXECUTABLE_NAME} PROPERTY C_STANDARD 17)
|
||||||
|
|
||||||
|
target_link_libraries(${STRAY_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm)
|
||||||
|
|
||||||
|
set_target_properties(${STRAY_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C)
|
||||||
|
|
||||||
|
install(TARGETS ${STRAY_EXECUTABLE_NAME} DESTINATION bin)
|
||||||
95
dev_in.c
95
dev_in.c
|
|
@ -1,6 +1,7 @@
|
||||||
#include "dev_in.h"
|
#include "dev_in.h"
|
||||||
#include "dev_hidraw.h"
|
#include "dev_hidraw.h"
|
||||||
#include "input_dev.h"
|
#include "input_dev.h"
|
||||||
|
#include "ipc.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "dev_evdev.h"
|
#include "dev_evdev.h"
|
||||||
#include "dev_iio.h"
|
#include "dev_iio.h"
|
||||||
|
|
@ -55,7 +56,7 @@ typedef struct dev_in {
|
||||||
|
|
||||||
} dev_in_t;
|
} dev_in_t;
|
||||||
|
|
||||||
static int send_message_from_iio(dev_in_iio_t *const in_iio) {
|
static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const messages, size_t messages_len) {
|
||||||
int res = -EIO;
|
int res = -EIO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -333,6 +334,15 @@ static void handle_rumble(dev_in_t *const in_devs, size_t in_devs_count, const o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_socket(void) {
|
||||||
|
int res = -ENODEV;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open_socket_err:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void* dev_in_thread_func(void *ptr) {
|
void* dev_in_thread_func(void *ptr) {
|
||||||
dev_in_data_t *const dev_in_data = (dev_in_data_t*)ptr;
|
dev_in_data_t *const dev_in_data = (dev_in_data_t*)ptr;
|
||||||
|
|
||||||
|
|
@ -364,7 +374,20 @@ void* dev_in_thread_func(void *ptr) {
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_SET(dev_in_data->out_message_pipe_fd, &read_fds);
|
|
||||||
|
if (dev_in_data->communication.type == ipc_unix_pipe) {
|
||||||
|
FD_SET(dev_in_data->communication.endpoint.pipe.out_message_pipe_fd, &read_fds);
|
||||||
|
} else if (dev_in_data->communication.type == ipc_client_socket) {
|
||||||
|
dev_in_data->communication.endpoint.socket = open_socket();
|
||||||
|
|
||||||
|
// do not do a thing! that will consume messages and they won't be available anymore!
|
||||||
|
if (dev_in_data->communication.endpoint.socket < 0) {
|
||||||
|
fprintf(stderr, "Unable to connect to server: %d -- will retry connection\n", dev_in_data->communication.endpoint.socket);
|
||||||
|
usleep(500000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < max_devices; ++i) {
|
for (size_t i = 0; i < max_devices; ++i) {
|
||||||
if (devices[i].type == DEV_IN_TYPE_EV) {
|
if (devices[i].type == DEV_IN_TYPE_EV) {
|
||||||
// device is present, query it in select
|
// device is present, query it in select
|
||||||
|
|
@ -415,9 +438,16 @@ void* dev_in_thread_func(void *ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for messages incoming like set leds or activate rumble
|
// check for messages incoming like set leds or activate rumble
|
||||||
if (FD_ISSET(dev_in_data->out_message_pipe_fd, &read_fds)) {
|
int out_message_fd = -1;
|
||||||
|
if (dev_in_data->communication.type == ipc_unix_pipe) {
|
||||||
|
out_message_fd = dev_in_data->communication.endpoint.pipe.out_message_pipe_fd;
|
||||||
|
} else if (dev_in_data->communication.type == ipc_client_socket) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(out_message_fd, &read_fds)) {
|
||||||
out_message_t out_msg;
|
out_message_t out_msg;
|
||||||
const ssize_t out_message_pipe_read_res = read(dev_in_data->out_message_pipe_fd, (void*)&out_msg, sizeof(out_message_t));
|
const ssize_t out_message_pipe_read_res = read(out_message_fd, (void*)&out_msg, sizeof(out_message_t));
|
||||||
if (out_message_pipe_read_res == sizeof(out_message_t)) {
|
if (out_message_pipe_read_res == sizeof(out_message_t)) {
|
||||||
if (out_msg.type == OUT_MSG_TYPE_RUMBLE) {
|
if (out_msg.type == OUT_MSG_TYPE_RUMBLE) {
|
||||||
handle_rumble(devices, max_devices, &out_msg.data.rumble);
|
handle_rumble(devices, max_devices, &out_msg.data.rumble);
|
||||||
|
|
@ -432,6 +462,12 @@ void* dev_in_thread_func(void *ptr) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Error reading from out_message_pipe_fd: got %zu bytes, expected %zu butes\n", out_message_pipe_read_res, sizeof(out_message_t));
|
fprintf(stderr, "Error reading from out_message_pipe_fd: got %zu bytes, expected %zu butes\n", out_message_pipe_read_res, sizeof(out_message_t));
|
||||||
|
|
||||||
|
// in case of an error reschedule to socket for reconnection
|
||||||
|
if (dev_in_data->communication.type == ipc_client_socket) {
|
||||||
|
close(out_message_fd);
|
||||||
|
dev_in_data->communication.endpoint.socket = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,32 +488,61 @@ void* dev_in_thread_func(void *ptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_message_t controller_msg[MAX_IN_MESSAGES];
|
||||||
|
size_t controller_msg_avail = sizeof(controller_msg) / sizeof(in_message_t);
|
||||||
|
int controller_msg_count = -EIO;
|
||||||
|
|
||||||
|
// the following part fills controller_msg and writes in controller_msg_count an error or the number of messages to be sent to the output device
|
||||||
if (devices[i].type == DEV_IN_TYPE_EV) {
|
if (devices[i].type == DEV_IN_TYPE_EV) {
|
||||||
evdev_collected_t coll = {
|
evdev_collected_t coll = {
|
||||||
.ev_count = 0
|
.ev_count = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
const int fill_res = fill_message_from_evdev(&devices[i].dev.evdev, &coll);
|
controller_msg_count = fill_message_from_evdev(&devices[i].dev.evdev, &coll);
|
||||||
if (fill_res != 0) {
|
if (controller_msg_count != 0) {
|
||||||
fprintf(stderr, "Unable to fill input_event(s) for device %zd: %d -- Will reconnect the device\n", i, fill_res);
|
fprintf(stderr, "Unable to fill input_event(s) for device %zd: %d -- Will reconnect the device\n", i, controller_msg_count);
|
||||||
evdev_close_device(&devices[i].dev.evdev);
|
evdev_close_device(&devices[i].dev.evdev);
|
||||||
devices[i].type = DEV_IN_TYPE_NONE;
|
devices[i].type = DEV_IN_TYPE_NONE;
|
||||||
} else {
|
continue;
|
||||||
dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, dev_in_data->in_message_pipe_fd, dev_in_data->input_dev_decl->dev[i]->user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data);
|
||||||
} else if (devices[i].type == DEV_IN_TYPE_IIO) {
|
} else if (devices[i].type == DEV_IN_TYPE_IIO) {
|
||||||
const int fill_res = send_message_from_iio(&devices[i].dev.iio);
|
controller_msg_count = map_message_from_iio(&devices[i].dev.iio, &controller_msg[0], controller_msg_avail);
|
||||||
if (fill_res != 0) {
|
if (controller_msg_count != 0) {
|
||||||
fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, fill_res);
|
fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count);
|
||||||
iio_close_device(&devices[i].dev.iio);
|
iio_close_device(&devices[i].dev.iio);
|
||||||
devices[i].type = DEV_IN_TYPE_NONE;
|
devices[i].type = DEV_IN_TYPE_NONE;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
} else if (devices[i].type == DEV_IN_TYPE_HIDRAW) {
|
} else if (devices[i].type == DEV_IN_TYPE_HIDRAW) {
|
||||||
const int fill_res = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), dev_in_data->in_message_pipe_fd, dev_in_data->input_dev_decl->dev[i]->user_data);
|
controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data);
|
||||||
if (fill_res != 0) {
|
if (controller_msg_count != 0) {
|
||||||
fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, fill_res);
|
fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count);
|
||||||
hidraw_close_device(&devices[i].dev.hidraw);
|
hidraw_close_device(&devices[i].dev.hidraw);
|
||||||
devices[i].type = DEV_IN_TYPE_NONE;
|
devices[i].type = DEV_IN_TYPE_NONE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send messages (if any)
|
||||||
|
if (controller_msg_count > 0) {
|
||||||
|
int in_message_fd = -1;
|
||||||
|
if (dev_in_data->communication.type == ipc_client_socket) {
|
||||||
|
in_message_fd = dev_in_data->communication.endpoint.socket;
|
||||||
|
} else if (dev_in_data->communication.type == ipc_unix_pipe) {
|
||||||
|
in_message_fd = dev_in_data->communication.endpoint.pipe.in_message_pipe_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int write_res = write(in_message_fd, (void*)&controller_msg[0], controller_msg_count);
|
||||||
|
if (write_res < 0) {
|
||||||
|
fprintf(stderr, "Error in writing input event messages: %d\n", write_res);
|
||||||
|
|
||||||
|
// in case of an error reschedule to socket for reconnection
|
||||||
|
if (dev_in_data->communication.type == ipc_client_socket) {
|
||||||
|
close(in_message_fd);
|
||||||
|
dev_in_data->communication.endpoint.socket = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
dev_in.h
9
dev_in.h
|
|
@ -1,8 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ipc.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "input_dev.h"
|
#include "input_dev.h"
|
||||||
|
|
||||||
|
#define MAX_IN_MESSAGES 8
|
||||||
|
|
||||||
typedef struct dev_in_data {
|
typedef struct dev_in_data {
|
||||||
size_t max_messages_in_flight;
|
size_t max_messages_in_flight;
|
||||||
|
|
||||||
|
|
@ -12,11 +15,7 @@ typedef struct dev_in_data {
|
||||||
// declarations of devices to monitor
|
// declarations of devices to monitor
|
||||||
input_dev_composite_t *input_dev_decl;
|
input_dev_composite_t *input_dev_decl;
|
||||||
|
|
||||||
// this pipe is reserved for reporting in_message_t
|
ipc_t communication;
|
||||||
int in_message_pipe_fd;
|
|
||||||
|
|
||||||
// this messages is reserved for receiving out_message_t
|
|
||||||
int out_message_pipe_fd;
|
|
||||||
|
|
||||||
} dev_in_data_t;
|
} dev_in_data_t;
|
||||||
|
|
||||||
|
|
|
||||||
107
dev_out.c
107
dev_out.c
|
|
@ -1,8 +1,10 @@
|
||||||
#include "dev_out.h"
|
#include "dev_out.h"
|
||||||
|
|
||||||
#include "devices_status.h"
|
#include "devices_status.h"
|
||||||
|
#include "message.h"
|
||||||
#include "virt_ds4.h"
|
#include "virt_ds4.h"
|
||||||
#include "virt_ds5.h"
|
#include "virt_ds5.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
static void handle_incoming_message_gamepad_action(
|
static void handle_incoming_message_gamepad_action(
|
||||||
const in_message_gamepad_action_t *const msg_payload,
|
const in_message_gamepad_action_t *const msg_payload,
|
||||||
|
|
@ -219,7 +221,22 @@ void *dev_out_thread_func(void *ptr) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_SET(dev_out->in_message_pipe_fd, &read_fds);
|
|
||||||
|
if (dev_out->communication.type == ipc_unix_pipe) {
|
||||||
|
FD_SET(dev_out->communication.endpoint.pipe.in_message_pipe_fd, &read_fds);
|
||||||
|
} else if (dev_out->communication.type == ipc_server_sockets) {
|
||||||
|
if (pthread_mutex_lock(&dev_out->communication.endpoint.ssocket.mutex) == 0) {
|
||||||
|
for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) {
|
||||||
|
const int fd = dev_out->communication.endpoint.ssocket.clients[i];
|
||||||
|
if (fd > 0) {
|
||||||
|
FD_SET(fd, &read_fds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&dev_out->communication.endpoint.ssocket.mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: FD_SET(current_mouse_fd, &read_fds);
|
// TODO: FD_SET(current_mouse_fd, &read_fds);
|
||||||
// TODO: FD_SET(current_keyboard_fd, &read_fds);
|
// TODO: FD_SET(current_keyboard_fd, &read_fds);
|
||||||
FD_SET(current_gamepad_fd, &read_fds);
|
FD_SET(current_gamepad_fd, &read_fds);
|
||||||
|
|
@ -242,23 +259,93 @@ void *dev_out_thread_func(void *ptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (FD_ISSET(current_gamepad_fd, &read_fds)) {
|
if (FD_ISSET(current_gamepad_fd, &read_fds)) {
|
||||||
|
const uint64_t prev_leds_events_count = dev_out->dev_stats.gamepad.leds_events_count;
|
||||||
|
const uint64_t prev_motors_events_count = dev_out->dev_stats.gamepad.rumble_events_count;
|
||||||
|
|
||||||
|
out_message_t out_msgs[4];
|
||||||
|
size_t out_msgs_count = 0;
|
||||||
if (current_gamepad == GAMEPAD_DUALSENSE) {
|
if (current_gamepad == GAMEPAD_DUALSENSE) {
|
||||||
virt_dualsense_event(&controller_data.ds5, &dev_out->dev_stats.gamepad, dev_out->out_message_pipe_fd);
|
virt_dualsense_event(&controller_data.ds5, &dev_out->dev_stats.gamepad);
|
||||||
} else if (current_gamepad == GAMEPAD_DUALSHOCK) {
|
} else if (current_gamepad == GAMEPAD_DUALSHOCK) {
|
||||||
virt_dualshock_event(&controller_data.ds4, &dev_out->dev_stats.gamepad, dev_out->out_message_pipe_fd);
|
virt_dualshock_event(&controller_data.ds4, &dev_out->dev_stats.gamepad);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t current_leds_events_count = dev_out->dev_stats.gamepad.leds_events_count;
|
||||||
|
const uint64_t current_motors_events_count = dev_out->dev_stats.gamepad.rumble_events_count;
|
||||||
|
|
||||||
|
if (current_leds_events_count != prev_leds_events_count) {
|
||||||
|
const out_message_t msg = {
|
||||||
|
.type = OUT_MSG_TYPE_LEDS,
|
||||||
|
.data = {
|
||||||
|
.leds = {
|
||||||
|
.r = dev_out->dev_stats.gamepad.leds_colors[0],
|
||||||
|
.g = dev_out->dev_stats.gamepad.leds_colors[1],
|
||||||
|
.b = dev_out->dev_stats.gamepad.leds_colors[2],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
out_msgs[out_msgs_count++] = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_motors_events_count != prev_motors_events_count) {
|
||||||
|
const out_message_t msg = {
|
||||||
|
.type = OUT_MSG_TYPE_RUMBLE,
|
||||||
|
.data = {
|
||||||
|
.rumble = {
|
||||||
|
.motors_left = dev_out->dev_stats.gamepad.motors_intensity[0],
|
||||||
|
.motors_right = dev_out->dev_stats.gamepad.motors_intensity[1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
out_msgs[out_msgs_count++] = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send out game-generated events to sockets
|
||||||
|
int fd = -1;
|
||||||
|
if (dev_out->communication.type == ipc_unix_pipe) {
|
||||||
|
fd = dev_out->communication.endpoint.pipe.out_message_pipe_fd;
|
||||||
|
} else if (dev_out->communication.type == ipc_server_sockets) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(dev_out->in_message_pipe_fd, &read_fds)) {
|
// read and handle incoming data: this data is packed into in_message_t
|
||||||
in_message_t incoming_message;
|
if (dev_out->communication.type == ipc_unix_pipe) {
|
||||||
size_t in_message_pipe_read_res = read(dev_out->in_message_pipe_fd, (void*)&incoming_message, sizeof(in_message_t));
|
if (FD_ISSET(dev_out->communication.endpoint.pipe.in_message_pipe_fd, &read_fds)) {
|
||||||
if (in_message_pipe_read_res == sizeof(in_message_t)) {
|
in_message_t incoming_message;
|
||||||
handle_incoming_message(&incoming_message, &dev_out->dev_stats);
|
const size_t in_message_pipe_read_res = read(dev_out->communication.endpoint.pipe.in_message_pipe_fd, (void*)&incoming_message, sizeof(in_message_t));
|
||||||
} else {
|
if (in_message_pipe_read_res == sizeof(in_message_t)) {
|
||||||
fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu butes\n", in_message_pipe_read_res, sizeof(in_message_t));
|
handle_incoming_message(&incoming_message, &dev_out->dev_stats);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu butes\n", in_message_pipe_read_res, sizeof(in_message_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dev_out->communication.type == ipc_server_sockets) {
|
||||||
|
if (pthread_mutex_lock(&dev_out->communication.endpoint.ssocket.mutex) == 0) {
|
||||||
|
for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) {
|
||||||
|
const int fd = dev_out->communication.endpoint.ssocket.clients[i];
|
||||||
|
if ((fd > 0) && (FD_ISSET(fd, &read_fds))) {
|
||||||
|
in_message_t incoming_message;
|
||||||
|
const size_t in_message_pipe_read_res = read(fd, (void*)&incoming_message, sizeof(in_message_t));
|
||||||
|
if (in_message_pipe_read_res == sizeof(in_message_t)) {
|
||||||
|
handle_incoming_message(&incoming_message, &dev_out->dev_stats);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu butes\n", in_message_pipe_read_res, sizeof(in_message_t));
|
||||||
|
dev_out->communication.endpoint.ssocket.clients[i] = -1;
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&dev_out->communication.endpoint.ssocket.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ipc.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "devices_status.h"
|
#include "devices_status.h"
|
||||||
|
|
||||||
|
|
@ -11,11 +12,7 @@ typedef enum dev_out_gamepad_device {
|
||||||
|
|
||||||
typedef struct dev_out_data {
|
typedef struct dev_out_data {
|
||||||
|
|
||||||
// this pipe is reserved for reporting in_message_t
|
ipc_t communication;
|
||||||
int in_message_pipe_fd;
|
|
||||||
|
|
||||||
// this messages is reserved for receiving out_message_t
|
|
||||||
int out_message_pipe_fd;
|
|
||||||
|
|
||||||
dev_out_gamepad_device_t gamepad;
|
dev_out_gamepad_device_t gamepad;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ void gamepad_status_init(gamepad_status_t *const stats) {
|
||||||
stats->accel[0] = 0;
|
stats->accel[0] = 0;
|
||||||
stats->accel[1] = 0;
|
stats->accel[1] = 0;
|
||||||
stats->accel[2] = 0;
|
stats->accel[2] = 0;
|
||||||
|
stats->leds_events_count = 0;
|
||||||
|
stats->leds_colors[0] = 0;
|
||||||
|
stats->leds_colors[1] = 0;
|
||||||
|
stats->leds_colors[2] = 0;
|
||||||
stats->flags = 0;
|
stats->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,9 @@ typedef struct gamepad_status {
|
||||||
uint64_t rumble_events_count;
|
uint64_t rumble_events_count;
|
||||||
uint8_t motors_intensity[2]; // 0 = left, 1 = right
|
uint8_t motors_intensity[2]; // 0 = left, 1 = right
|
||||||
|
|
||||||
|
uint64_t leds_events_count;
|
||||||
|
uint8_t leds_colors[3]; // r | g | b
|
||||||
|
|
||||||
volatile uint32_t flags;
|
volatile uint32_t flags;
|
||||||
|
|
||||||
} gamepad_status_t;
|
} gamepad_status_t;
|
||||||
|
|
|
||||||
10
input_dev.h
10
input_dev.h
|
|
@ -17,8 +17,8 @@ typedef struct evdev_collected {
|
||||||
* A function with this signature grapbs input_event data and sends to the pipe messages
|
* A function with this signature grapbs input_event data and sends to the pipe messages
|
||||||
* constructed from that data.
|
* constructed from that data.
|
||||||
*/
|
*/
|
||||||
typedef void (*ev_map)(const evdev_collected_t *const e, int in_messages_pipe_fd, void* user_data);
|
typedef int (*ev_map)(const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data);
|
||||||
typedef int (*hidraw_map)(int hidraw_fd, int in_messages_pipe_fd, void* user_data);
|
typedef int (*hidraw_map)(int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data);
|
||||||
|
|
||||||
typedef enum input_dev_type {
|
typedef enum input_dev_type {
|
||||||
input_dev_type_uinput,
|
input_dev_type_uinput,
|
||||||
|
|
@ -92,9 +92,3 @@ typedef struct input_dev_composite {
|
||||||
platform_deinit deinit_fn;
|
platform_deinit deinit_fn;
|
||||||
|
|
||||||
} input_dev_composite_t;
|
} input_dev_composite_t;
|
||||||
|
|
||||||
uint32_t input_filter_imu_identity(struct input_event* events, size_t* size, uint32_t* count, uint32_t* flags);
|
|
||||||
|
|
||||||
uint32_t input_filter_identity(struct input_event* events, size_t* size, uint32_t* count, uint32_t* flags);
|
|
||||||
|
|
||||||
uint32_t input_filter_asus_kb(struct input_event*, size_t*, uint32_t*, uint32_t* flags);
|
|
||||||
|
|
|
||||||
38
ipc.h
Normal file
38
ipc.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rogue_enemy.h"
|
||||||
|
|
||||||
|
#define MAX_CONNECTED_CLIENTS 8
|
||||||
|
|
||||||
|
typedef struct ipc_strategy_socket {
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
int clients[MAX_CONNECTED_CLIENTS];
|
||||||
|
} ipc_strategy_socket_t;
|
||||||
|
|
||||||
|
typedef struct ipc_strategy_pipe {
|
||||||
|
|
||||||
|
// this pipe is reserved for reporting in_message_t
|
||||||
|
int in_message_pipe_fd;
|
||||||
|
|
||||||
|
// this messages is reserved for receiving out_message_t
|
||||||
|
int out_message_pipe_fd;
|
||||||
|
|
||||||
|
} ipc_strategy_pipe_t;
|
||||||
|
|
||||||
|
typedef enum ipc_strategy {
|
||||||
|
ipc_unix_pipe,
|
||||||
|
ipc_server_sockets,
|
||||||
|
ipc_client_socket,
|
||||||
|
} ipc_strategy_t;
|
||||||
|
|
||||||
|
typedef struct ipc {
|
||||||
|
ipc_strategy_t type;
|
||||||
|
union {
|
||||||
|
ipc_strategy_pipe_t pipe;
|
||||||
|
ipc_strategy_socket_t ssocket;
|
||||||
|
int socket;
|
||||||
|
} endpoint;
|
||||||
|
|
||||||
|
} ipc_t;
|
||||||
|
|
||||||
|
#define SERVER_PATH "/tmp/server.sock"
|
||||||
13
legion_go.c
13
legion_go.c
|
|
@ -40,9 +40,11 @@ static struct llg_hidraw_data {
|
||||||
uint8_t last_packet[64];
|
uint8_t last_packet[64];
|
||||||
} llg_hidraw_user_data;
|
} llg_hidraw_user_data;
|
||||||
|
|
||||||
static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_data) {
|
static int llg_hidraw_map(int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) {
|
||||||
struct llg_hidraw_data *const llg_data = (struct llg_hidraw_data*)user_data;
|
struct llg_hidraw_data *const llg_data = (struct llg_hidraw_data*)user_data;
|
||||||
|
|
||||||
|
int msg_count = 0;
|
||||||
|
|
||||||
int read_res = read(hidraw_fd, llg_data->last_packet, sizeof(llg_data->last_packet));
|
int read_res = read(hidraw_fd, llg_data->last_packet, sizeof(llg_data->last_packet));
|
||||||
if (read_res != 64) {
|
if (read_res != 64) {
|
||||||
fprintf(stderr, "Error reading from hidraw device\n");
|
fprintf(stderr, "Error reading from hidraw device\n");
|
||||||
|
|
@ -64,16 +66,11 @@ static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_dat
|
||||||
};
|
};
|
||||||
|
|
||||||
// this does send messages to the output device
|
// this does send messages to the output device
|
||||||
|
messages[msg_count++] = current_message;
|
||||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
|
||||||
if (in_message_pipe_write_res != sizeof(in_message_t)) {
|
|
||||||
fprintf(stderr, "Unable to write data for L4 to the in_message pipe: %zu\n", in_message_pipe_write_res);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// successful return
|
// successful return
|
||||||
return 0;
|
return msg_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static input_dev_t in_hidraw_dev = {
|
static input_dev_t in_hidraw_dev = {
|
||||||
|
|
|
||||||
54
main.c
54
main.c
|
|
@ -27,9 +27,6 @@ void sig_handler(int signo)
|
||||||
|
|
||||||
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
|
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
|
||||||
|
|
||||||
dev_in_data_t dev_in_thread_data;
|
|
||||||
dev_out_data_t dev_out_thread_data;
|
|
||||||
|
|
||||||
controller_settings_t settings;
|
controller_settings_t settings;
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
|
|
@ -38,13 +35,6 @@ int main(int argc, char ** argv) {
|
||||||
init_config(&settings);
|
init_config(&settings);
|
||||||
fill_config(&settings, configuration_file);
|
fill_config(&settings, configuration_file);
|
||||||
|
|
||||||
/*
|
|
||||||
const int logic_creation_res = logic_create(&global_logic);
|
|
||||||
if (logic_creation_res < 0) {
|
|
||||||
fprintf(stderr, "Unable to create logic: %d", logic_creation_res);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
input_dev_composite_t* in_devs = NULL;
|
input_dev_composite_t* in_devs = NULL;
|
||||||
|
|
||||||
int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK);
|
int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK);
|
||||||
|
|
@ -65,29 +55,20 @@ int main(int argc, char ** argv) {
|
||||||
}
|
}
|
||||||
close(dmi_name_fd);
|
close(dmi_name_fd);
|
||||||
|
|
||||||
int dev_in_thread_creation = -1;
|
|
||||||
int dev_out_thread_creation = -1;
|
|
||||||
|
|
||||||
int out_message_pipes[2];
|
|
||||||
pipe(out_message_pipes);
|
|
||||||
|
|
||||||
int in_message_pipes[2];
|
|
||||||
pipe(in_message_pipes);
|
|
||||||
|
|
||||||
// populate the input device thread data
|
// populate the input device thread data
|
||||||
dev_in_thread_data.timeout_ms = 400;
|
dev_in_data_t dev_in_thread_data = {
|
||||||
dev_in_thread_data.in_message_pipe_fd = in_message_pipes[1];
|
.timeout_ms = 1200,
|
||||||
dev_in_thread_data.out_message_pipe_fd = out_message_pipes[0];
|
.input_dev_decl = in_devs,
|
||||||
dev_in_thread_data.input_dev_decl = in_devs;
|
.communication = {
|
||||||
|
.type = ipc_client_socket,
|
||||||
|
.endpoint = {
|
||||||
|
.socket = -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// populate the output device thread data
|
|
||||||
//dev_out_thread_data.timeout_ms = 400;
|
|
||||||
dev_out_thread_data.in_message_pipe_fd = in_message_pipes[0];
|
|
||||||
dev_out_thread_data.out_message_pipe_fd = out_message_pipes[1];
|
|
||||||
dev_out_thread_data.gamepad = GAMEPAD_DUALSENSE;
|
|
||||||
|
|
||||||
pthread_t dev_in_thread;
|
pthread_t dev_in_thread;
|
||||||
dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data));
|
const int dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data));
|
||||||
if (dev_in_thread_creation != 0) {
|
if (dev_in_thread_creation != 0) {
|
||||||
fprintf(stderr, "Error creating dev_in thread: %d\n", dev_in_thread_creation);
|
fprintf(stderr, "Error creating dev_in thread: %d\n", dev_in_thread_creation);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
@ -95,15 +76,6 @@ int main(int argc, char ** argv) {
|
||||||
goto main_err;
|
goto main_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_t dev_out_thread;
|
|
||||||
dev_out_thread_creation = pthread_create(&dev_out_thread, NULL, dev_out_thread_func, (void*)(&dev_out_thread_data));
|
|
||||||
if (dev_out_thread_creation != 0) {
|
|
||||||
fprintf(stderr, "Error creating dev_out thread: %d\n", dev_out_thread_creation);
|
|
||||||
ret = -1;
|
|
||||||
//logic_request_termination(&global_logic);
|
|
||||||
goto main_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO: once the application is able to exit de-comment this
|
// TODO: once the application is able to exit de-comment this
|
||||||
__sighandler_t sigint_hndl = signal(SIGINT, sig_handler);
|
__sighandler_t sigint_hndl = signal(SIGINT, sig_handler);
|
||||||
|
|
@ -118,9 +90,5 @@ main_err:
|
||||||
pthread_join(dev_in_thread, NULL);
|
pthread_join(dev_in_thread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_out_thread_creation == 0) {
|
|
||||||
pthread_join(dev_out_thread, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
rog_ally.c
26
rog_ally.c
|
|
@ -432,7 +432,9 @@ static const uint8_t rc71l_mode_switch_commands[][23][64] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void asus_kbd_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd, void* user_data) {
|
int asus_kbd_ev_map(const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data) {
|
||||||
|
int written_msg = 0;
|
||||||
|
|
||||||
if ( // this is what happens at release of the left-screen button of the ROG Ally
|
if ( // this is what happens at release of the left-screen button of the ROG Ally
|
||||||
(e->ev_count == 2) &&
|
(e->ev_count == 2) &&
|
||||||
(e->ev[0].type == EV_MSC) &&
|
(e->ev[0].type == EV_MSC) &&
|
||||||
|
|
@ -449,10 +451,7 @@ void asus_kbd_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
messages[written_msg++] = current_message;
|
||||||
if (in_message_pipe_write_res != sizeof(in_message_t)) {
|
|
||||||
fprintf(stderr, "Unable to write data for MENU to the in_message pipe: %zu\n", in_message_pipe_write_res);
|
|
||||||
}
|
|
||||||
} else if ( // this is what happens at release of the right-screen button of the ROG Ally
|
} else if ( // this is what happens at release of the right-screen button of the ROG Ally
|
||||||
(e->ev_count == 2) &&
|
(e->ev_count == 2) &&
|
||||||
(e->ev[0].type == EV_MSC) &&
|
(e->ev[0].type == EV_MSC) &&
|
||||||
|
|
@ -469,10 +468,7 @@ void asus_kbd_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
messages[written_msg++] = current_message;
|
||||||
if (in_message_pipe_write_res != sizeof(in_message_t)) {
|
|
||||||
fprintf(stderr, "Unable to write data for QAM to the in_message pipe: %zu\n", in_message_pipe_write_res);
|
|
||||||
}
|
|
||||||
} else if (
|
} else if (
|
||||||
(e->ev_count == 2) &&
|
(e->ev_count == 2) &&
|
||||||
(e->ev[0].type == EV_MSC) &&
|
(e->ev[0].type == EV_MSC) &&
|
||||||
|
|
@ -493,10 +489,7 @@ void asus_kbd_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
messages[written_msg++] = current_message;
|
||||||
if (in_message_pipe_write_res != sizeof(in_message_t)) {
|
|
||||||
fprintf(stderr, "Unable to write data for L5 to the in_message pipe: %zu\n", in_message_pipe_write_res);
|
|
||||||
}
|
|
||||||
} else if (
|
} else if (
|
||||||
(e->ev_count == 2) &&
|
(e->ev_count == 2) &&
|
||||||
(e->ev[0].type == EV_MSC) &&
|
(e->ev[0].type == EV_MSC) &&
|
||||||
|
|
@ -517,11 +510,10 @@ void asus_kbd_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
messages[written_msg++] = current_message;
|
||||||
if (in_message_pipe_write_res != sizeof(in_message_t)) {
|
|
||||||
fprintf(stderr, "Unable to write data for R5 to the in_message pipe: %zu\n", in_message_pipe_write_res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return written_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hidraw_filters_t n_key_hidraw_filters = {
|
static hidraw_filters_t n_key_hidraw_filters = {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include <linux/hidraw.h>
|
#include <linux/hidraw.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
|
|
|
||||||
132
stray_ally.c
Normal file
132
stray_ally.c
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "input_dev.h"
|
||||||
|
#include "dev_in.h"
|
||||||
|
#include "dev_out.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
#include "rog_ally.h"
|
||||||
|
#include "legion_go.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
logic_t global_logic;
|
||||||
|
|
||||||
|
static output_dev_t out_gamepadd_dev = {
|
||||||
|
.logic = &global_logic,
|
||||||
|
};
|
||||||
|
|
||||||
|
void sig_handler(int signo)
|
||||||
|
{
|
||||||
|
if (signo == SIGINT) {
|
||||||
|
logic_request_termination(&global_logic);
|
||||||
|
printf("Received SIGINT\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
|
||||||
|
|
||||||
|
controller_settings_t settings;
|
||||||
|
|
||||||
|
int main(int argc, char ** argv) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
init_config(&settings);
|
||||||
|
fill_config(&settings, configuration_file);
|
||||||
|
|
||||||
|
// populate the output device thread data
|
||||||
|
dev_out_data_t dev_out_thread_data = {
|
||||||
|
.communication = {
|
||||||
|
.type = ipc_server_sockets,
|
||||||
|
.endpoint = {
|
||||||
|
.ssocket = {
|
||||||
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||||
|
.clients = { -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.gamepad = GAMEPAD_DUALSENSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
pthread_t dev_out_thread;
|
||||||
|
const int dev_out_thread_creation = pthread_create(&dev_out_thread, NULL, dev_out_thread_func, (void*)(&dev_out_thread_data));
|
||||||
|
if (dev_out_thread_creation != 0) {
|
||||||
|
fprintf(stderr, "Error creating dev_out thread: %d\n", dev_out_thread_creation);
|
||||||
|
ret = -1;
|
||||||
|
//logic_request_termination(&global_logic);
|
||||||
|
goto main_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd=-1;
|
||||||
|
int rc, length;
|
||||||
|
struct sockaddr_un serveraddr;
|
||||||
|
do {
|
||||||
|
sd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (sd < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "socket() failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||||
|
serveraddr.sun_family = AF_UNIX;
|
||||||
|
strcpy(serveraddr.sun_path, SERVER_PATH);
|
||||||
|
|
||||||
|
int rc = bind(sd, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr));
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
perror("bind() failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const int client_fd = accept(sd, NULL, NULL);
|
||||||
|
if (client_fd < 0) {
|
||||||
|
fprintf(stderr, "Error in getting a client connected: %d\n", client_fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// here the client_fd is good
|
||||||
|
if (pthread_mutex_lock(&dev_out_thread_data.communication.endpoint.ssocket.mutex) == 0) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_CONNECTED_CLIENTS; ++i) {
|
||||||
|
if (dev_out_thread_data.communication.endpoint.ssocket.clients[i] == -1) {
|
||||||
|
dev_out_thread_data.communication.endpoint.ssocket.clients[i] = client_fd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == MAX_CONNECTED_CLIENTS) {
|
||||||
|
fprintf(stderr, "Could not find a free spot fot the incoming client -- client will be rejected\n");
|
||||||
|
close(client_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&dev_out_thread_data.communication.endpoint.ssocket.mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (sd != -1) {
|
||||||
|
close(sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(SERVER_PATH);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: once the application is able to exit de-comment this
|
||||||
|
__sighandler_t sigint_hndl = signal(SIGINT, sig_handler);
|
||||||
|
if (sigint_hndl == SIG_ERR) {
|
||||||
|
fprintf(stderr, "Error registering SIGINT handler\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
main_err:
|
||||||
|
if (dev_out_thread_creation == 0) {
|
||||||
|
pthread_join(dev_out_thread, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
57
virt_ds4.c
57
virt_ds4.c
|
|
@ -402,7 +402,7 @@ int virt_dualshock_get_fd(virt_dualshock_t *const in_gamepad) {
|
||||||
return in_gamepad->fd;
|
return in_gamepad->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *const out_device_status, int out_message_pipe_fd) {
|
int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *const out_device_status) {
|
||||||
struct uhid_event ev;
|
struct uhid_event ev;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
|
@ -505,58 +505,21 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons
|
||||||
const uint8_t lightbar_blink_off = ev.u.output.data[10];
|
const uint8_t lightbar_blink_off = ev.u.output.data[10];
|
||||||
|
|
||||||
if ((valid_flag0 & DS4_OUTPUT_VALID_FLAG0_LED)) {
|
if ((valid_flag0 & DS4_OUTPUT_VALID_FLAG0_LED)) {
|
||||||
const out_message_t msg = {
|
out_device_status->leds_colors[0] = lightbar_red;
|
||||||
.type = OUT_MSG_TYPE_LEDS,
|
out_device_status->leds_colors[1] = lightbar_green;
|
||||||
.data = {
|
out_device_status->leds_colors[2] = lightbar_blue;
|
||||||
.leds = {
|
out_device_status->leds_events_count++;
|
||||||
.r = lightbar_red,
|
|
||||||
.g = lightbar_green,
|
|
||||||
.b = lightbar_blue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int write_res = write(out_message_pipe_fd, (void*)&msg, sizeof(msg));
|
|
||||||
if (write_res != 0) {
|
|
||||||
return write_res;
|
|
||||||
}
|
|
||||||
} else if (valid_flag0 & DS4_OUTPUT_VALID_FLAG0_LED_BLINK) {
|
} else if (valid_flag0 & DS4_OUTPUT_VALID_FLAG0_LED_BLINK) {
|
||||||
const out_message_t msg = {
|
out_device_status->leds_colors[0] = lightbar_red;
|
||||||
.type = OUT_MSG_TYPE_LEDS,
|
out_device_status->leds_colors[1] = lightbar_green;
|
||||||
.data = {
|
out_device_status->leds_colors[2] = lightbar_blue;
|
||||||
.leds = {
|
out_device_status->leds_events_count++;
|
||||||
.r = lightbar_red,
|
|
||||||
.g = lightbar_green,
|
|
||||||
.b = lightbar_blue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int write_res = write(out_message_pipe_fd, (void*)&msg, sizeof(msg));
|
|
||||||
if (write_res != 0) {
|
|
||||||
return write_res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((valid_flag0 & DS4_OUTPUT_VALID_FLAG0_MOTOR)) {
|
if ((valid_flag0 & DS4_OUTPUT_VALID_FLAG0_MOTOR)) {
|
||||||
out_device_status->motors_intensity[0] = motor_left;
|
out_device_status->motors_intensity[0] = motor_left;
|
||||||
out_device_status->motors_intensity[1] = motor_right;
|
out_device_status->motors_intensity[1] = motor_right;
|
||||||
++out_device_status->rumble_events_count;
|
out_device_status->rumble_events_count++;
|
||||||
|
|
||||||
const out_message_t msg = {
|
|
||||||
.type = OUT_MSG_TYPE_RUMBLE,
|
|
||||||
.data = {
|
|
||||||
.rumble = {
|
|
||||||
.motors_left = motor_left,
|
|
||||||
.motors_right = motor_right,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int write_res = write(out_message_pipe_fd, (void*)&msg, sizeof(msg));
|
|
||||||
if (write_res != 0) {
|
|
||||||
return write_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamepad->debug) {
|
if (gamepad->debug) {
|
||||||
printf(
|
printf(
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ int virt_dualshock_init(virt_dualshock_t *const gamepad);
|
||||||
|
|
||||||
int virt_dualshock_get_fd(virt_dualshock_t *const gamepad);
|
int virt_dualshock_get_fd(virt_dualshock_t *const gamepad);
|
||||||
|
|
||||||
int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *const out_device_status, int out_message_pipe_fd);
|
int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *const out_device_status);
|
||||||
|
|
||||||
void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf);
|
void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf);
|
||||||
|
|
||||||
|
|
|
||||||
36
virt_ds5.c
36
virt_ds5.c
|
|
@ -142,7 +142,7 @@ int virt_dualsense_get_fd(virt_dualsense_t *const in_gamepad) {
|
||||||
return in_gamepad->fd;
|
return in_gamepad->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *const out_device_status, int out_message_pipe_fd)
|
int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *const out_device_status)
|
||||||
{
|
{
|
||||||
struct uhid_event ev;
|
struct uhid_event ev;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
@ -235,21 +235,6 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons
|
||||||
out_device_status->motors_intensity[1] = motor_right;
|
out_device_status->motors_intensity[1] = motor_right;
|
||||||
++out_device_status->rumble_events_count;
|
++out_device_status->rumble_events_count;
|
||||||
|
|
||||||
const out_message_t msg = {
|
|
||||||
.type = OUT_MSG_TYPE_RUMBLE,
|
|
||||||
.data = {
|
|
||||||
.rumble = {
|
|
||||||
.motors_left = motor_left,
|
|
||||||
.motors_right = motor_right,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int write_res = write(out_message_pipe_fd, (void*)&msg, sizeof(msg));
|
|
||||||
if (write_res != 0) {
|
|
||||||
return write_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamepad->debug) {
|
if (gamepad->debug) {
|
||||||
printf(
|
printf(
|
||||||
"Updated rumble -- motor_left: %d, motor_right: %d, valid_flag0; %d, valid_flag1: %d\n",
|
"Updated rumble -- motor_left: %d, motor_right: %d, valid_flag0; %d, valid_flag1: %d\n",
|
||||||
|
|
@ -263,21 +248,10 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_flag1 & DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE) {
|
if (valid_flag1 & DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE) {
|
||||||
const out_message_t msg = {
|
out_device_status->leds_colors[0] = lightbar_red;
|
||||||
.type = OUT_MSG_TYPE_LEDS,
|
out_device_status->leds_colors[1] = lightbar_green;
|
||||||
.data = {
|
out_device_status->leds_colors[2] = lightbar_blue;
|
||||||
.leds = {
|
out_device_status->leds_events_count++;
|
||||||
.r = lightbar_red,
|
|
||||||
.g = lightbar_green,
|
|
||||||
.b = lightbar_blue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int write_res = write(out_message_pipe_fd, (void*)&msg, sizeof(msg));
|
|
||||||
if (write_res != 0) {
|
|
||||||
return write_res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ int virt_dualsense_init(virt_dualsense_t *const gamepad);
|
||||||
|
|
||||||
int virt_dualsense_get_fd(virt_dualsense_t *const gamepad);
|
int virt_dualsense_get_fd(virt_dualsense_t *const gamepad);
|
||||||
|
|
||||||
int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *const out_device_status, int out_message_pipe_fd);
|
int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *const out_device_status);
|
||||||
|
|
||||||
void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf);
|
void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf);
|
||||||
|
|
||||||
|
|
|
||||||
17
xbox360.c
17
xbox360.c
|
|
@ -1,8 +1,9 @@
|
||||||
#include "xbox360.h"
|
#include "xbox360.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
void xbox360_ev_map(const evdev_collected_t *const coll, int in_messages_pipe_fd, void* user_data) {
|
int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const messages, size_t messages_len, void* user_data) {
|
||||||
const xbox360_settings_t *const settings = (xbox360_settings_t*)user_data;
|
const xbox360_settings_t *const settings = (xbox360_settings_t*)user_data;
|
||||||
|
int written_msg = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < coll->ev_count; ++i) {
|
for (uint32_t i = 0; i < coll->ev_count; ++i) {
|
||||||
if (coll->ev[i].type == EV_KEY) {
|
if (coll->ev[i].type == EV_KEY) {
|
||||||
|
|
@ -45,10 +46,11 @@ void xbox360_ev_map(const evdev_collected_t *const coll, int in_messages_pipe_fd
|
||||||
current_message.data.action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER;
|
current_message.data.action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the button event over the pipe
|
if (written_msg == (messages_len-1)) {
|
||||||
if (write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t)) != sizeof(in_message_t)) {
|
return -ENOMEM;
|
||||||
fprintf(stderr, "Unable to write gamepad data to the in_message pipe\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messages[written_msg++] = current_message;
|
||||||
} else if (coll->ev[i].type == EV_ABS) {
|
} else if (coll->ev[i].type == EV_ABS) {
|
||||||
in_message_t current_message = {
|
in_message_t current_message = {
|
||||||
.type = GAMEPAD_SET_ELEMENT,
|
.type = GAMEPAD_SET_ELEMENT,
|
||||||
|
|
@ -80,10 +82,11 @@ void xbox360_ev_map(const evdev_collected_t *const coll, int in_messages_pipe_fd
|
||||||
current_message.data.gamepad_set.status.btn = coll->ev[i].value;
|
current_message.data.gamepad_set.status.btn = coll->ev[i].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the button event over the pipe
|
if (written_msg == (messages_len-1)) {
|
||||||
if (write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t)) != sizeof(in_message_t)) {
|
return -ENOMEM;
|
||||||
fprintf(stderr, "Unable to write gamepad data to the in_message pipe\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messages[written_msg++] = current_message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ typedef struct xbox360_settings {
|
||||||
bool nintendo_layout;
|
bool nintendo_layout;
|
||||||
} xbox360_settings_t;
|
} xbox360_settings_t;
|
||||||
|
|
||||||
void xbox360_ev_map(const evdev_collected_t *const e, int in_messages_pipe_fd, void* user_data);
|
int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const messages, size_t messages_len, void* user_data);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue