gamesir-keepalive/gamesir-keepalive.c

114 lines
3 KiB
C

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#define DEV_INPUT_BY_ID "/dev/input/by-id"
#define BUFFER_SIZE 64
static volatile sig_atomic_t g_running = 1;
static void handle_signal(int sig) {
(void)sig;
g_running = 0;
}
/**
* Searches /dev/input/by-id for a GameSir or vendor ID 3537 joystick device.
* Writes matched path into out_path (capacity: max_len).
* Returns 1 if found, 0 if not found.
*/
static int find_gamesir_device(char *out_path, size_t max_len) {
DIR *dir = opendir(DEV_INPUT_BY_ID);
if (!dir) {
return 0;
}
struct dirent *entry;
int found = 0;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.') {
continue;
}
const char *name = entry->d_name;
/* Matches Python pattern: *GameSir*joystick* or *3537*joystick* */
if (strstr(name, "joystick") != NULL) {
if (strstr(name, "GameSir") != NULL || strstr(name, "3537") != NULL) {
int written = snprintf(out_path, max_len, "%s/%s", DEV_INPUT_BY_ID, name);
if (written > 0 && (size_t)written < max_len) {
found = 1;
break;
}
}
}
}
closedir(dir);
return found;
}
int main(void) {
/* Setup line buffering for stdout so journalctl logs are immediate */
setvbuf(stdout, NULL, _IOLBF, 0);
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
printf("Iniciando GameSir Keepalive Service (C native)...\n");
char dev_path[512];
unsigned char buffer[BUFFER_SIZE];
while (g_running) {
if (!find_gamesir_device(dev_path, sizeof(dev_path))) {
sleep(1);
continue;
}
printf("Dispositivo GameSir encontrado em %s. Abrindo descritor...\n", dev_path);
int fd = open(dev_path, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Aviso: Falha ao abrir %s: %s. Aguardando...\n", dev_path, strerror(errno));
sleep(1);
continue;
}
printf("Conexão mantida ativa com sucesso.\n");
while (g_running) {
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read < 0) {
if (errno == EINTR) {
continue;
}
printf("Dispositivo desconectado ou indisponível: %s. Aguardando reconexão...\n", strerror(errno));
break;
} else if (bytes_read == 0) {
printf("Fim do fluxo do dispositivo (EOF). Aguardando reconexão...\n");
break;
}
}
close(fd);
if (g_running) {
sleep(1);
}
}
printf("GameSir Keepalive Service finalizado.\n");
return 0;
}