114 lines
3 KiB
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;
|
|
}
|