#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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); }