Inial commit

This commit is contained in:
Carl Philipp Klemm 2026-02-06 09:28:04 +01:00
commit e7656962d2
3 changed files with 169 additions and 0 deletions

151
main.c Normal file
View file

@ -0,0 +1,151 @@
#include <stdio.h>
#include <linux/types.h>
#include <linux/input.h>
#include <linux/hidraw.h>
#include <linux/uinput.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
struct key
{
int linux_code;
int onkio_code;
};
struct key keys[] =
{
{KEY_PLAY, 3471},
{KEY_V, 3983},
{KEY_Q, 911},
{KEY_A, 943},
{KEY_FASTFORWARD, 2959},
{KEY_REWIND, 1935},
{-1, -1}
};
static int register_uinput_device(const char* uinputdev, const char* devname, uint16_t vid, uint16_t pid)
{
int fd = open(uinputdev, O_RDWR);
if(fd < 0)
return fd;
struct uinput_setup dev = {};
size_t len = strlen(devname);
if(len > UINPUT_MAX_NAME_SIZE)
len = UINPUT_MAX_NAME_SIZE;
strncpy(dev.name, devname, len);
dev.id.bustype = BUS_VIRTUAL;
dev.id.vendor = vid;
dev.id.product = pid;
ioctl(fd, UI_SET_EVBIT, EV_KEY);
for(size_t i = 0; keys[i].linux_code > 0; ++i)
ioctl(fd, UI_SET_KEYBIT, keys[i].linux_code);
int ret = ioctl(fd, UI_DEV_SETUP, &dev);
if(ret < 0)
{
close(fd);
return ret;
}
ret = ioctl(fd, UI_DEV_CREATE);
if(ret < 0)
{
close(fd);
return ret;
}
return fd;
}
int main(int argc, char** argv)
{
if(argc < 2)
{
printf("usage: %s [BIND ADDR]\n", argv[0]);
return 1;
}
char* addrstr = argv[1];
int uinputfd = register_uinput_device("/dev/uinput", "ONKIO RI", 0xfefe, 0xfefe);
if(uinputfd < 0)
{
fprintf(stderr, "Could not create uinput device: %s\n", strerror(errno));
return 1;
}
int socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(socketfd < 0)
{
fprintf(stderr, "Could not create socket device: %s\n", strerror(errno));
return 1;
}
in_addr_t addr = inet_addr(addrstr);
struct sockaddr_in sockaddr = {.sin_family = AF_INET, .sin_port = htons(40586), .sin_addr = {.s_addr = INADDR_ANY}};
int ret = bind(socketfd, (const struct sockaddr*)&sockaddr, sizeof(sockaddr));
if(ret < 0)
{
fprintf(stderr, "Could not bind to socket: %s\n", strerror(errno));
return 1;
}
char buffer[65] = {};
while(true)
{
ret = read(socketfd, buffer, 64);
if(ret < 0)
{
fprintf(stderr, "Could not read from to socket: %s\n", strerror(errno));
return 1;
}
const char* header = "RI_MESSAGE: ";
if(strncmp(header, buffer, strlen(header)) == 0 && ret > strlen(header)+1)
{
int code = atoi(buffer+strlen(header));
bool found = false;
for(size_t i = 0; keys[i].linux_code > 0; ++i)
{
if(keys[i].onkio_code == code)
{
struct input_event ev = {};
ev.type = EV_KEY;
ev.code = keys[i].linux_code;
ev.value = 1;
if(write(uinputfd, &ev, sizeof(ev)) != sizeof(ev))
return -1;
ev.value = 0;
if(write(uinputfd, &ev, sizeof(ev)) != sizeof(ev))
return -1;
gettimeofday(&ev.time, NULL);
ev.type = EV_SYN;
ev.code = SYN_REPORT;
ev.value = 0;
if(write(uinputfd, &ev, sizeof(ev)) != sizeof(ev))
return -2;
found = true;
}
}
printf("Got %s code %i\n", found ? "known" : "unkown", code);
}
}
close(uinputfd);
close(socketfd);
}