Files
neutrino/src/rcsim.c
svenhoefer a4c59199a7 - remove RC_HW_TRIPLEDRAGON
Signed-off-by: Thilo Graf <dbt@novatux.de>
2021-11-03 12:13:18 +01:00

254 lines
5.9 KiB
C

/******************************************************************************
* rcsim - rcsim.c
*
* simulates the remote control, sends the requested key
*
* (c) 2003 Carsten Juttner (carjay@gmx.net)
* (c) 2009 Stefan Seyfried, add code to use the neutrino socket
* (c) 2011 Stefan Seyfried, convert driver/rcinput.h via script to
* rcsim.h for automated import of new keys
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* The Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA.
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <error.h>
#include <sys/socket.h>
#include <sys/un.h>
#define NEUTRINO_SOCKET "/tmp/neutrino.sock"
/* those structs / values are stolen from libeventserver */
struct eventHead
{
unsigned int eventID;
unsigned int initiatorID;
unsigned int dataSize;
};
enum initiators
{
INITID_CONTROLD,
INITID_SECTIONSD,
INITID_ZAPIT,
INITID_TIMERD,
INITID_HTTPD,
INITID_NEUTRINO,
INITID_GENERIC_INPUT_EVENT_PROVIDER
};
#include "rcsim.h"
void usage(char *n)
{
unsigned int keynum = sizeof(keyname) / sizeof(struct key);
unsigned int i;
#if defined (EVENTDEV)
printf("rcsim v1.2\nUsage: %s <keyname> [<time>] [<repeat>]\n"
" <keyname> is an excerpt of the 'KEY_FOO'-names in <driver/rcinput.h>,\n"
" <time> is how long a code is repeatedly sent,\n"
" unit is seconds, default is 0 = sent only once\n"
" <repeat> what time is waited until a new code is sent\n"
" (if <time> is greater than 0), unit is milliseconds,\n"
" default is 500\n\n"
" Example:\n"
" %s KEY_1\n"
" ; KEY_1 sent once\n"
" %s KEY_OK 2 250\n"
" ; KEY_OK sent every 250ms for 2 seconds\n\n"
" Keys:", n, n, n);
#else
printf("rcsim v1.2\nUsage: %s <keyname>\n\n"
" Keys:", n);
#endif
for (i = 0; i < keynum;)
{
if ((i % 4) == 0)
printf("\n %-20s", keyname[i++].name);
else
printf("%-20s", keyname[i++].name);
}
printf("\n\n");
}
/* we could also use the neutrino socket on the dbox, but this needs more testing.
so leave it as is for now */
#if defined (EVENTDEV)
int push(int ev, unsigned int code, unsigned int value)
{
struct input_event iev;
iev.type = EV_KEY;
iev.code = code;
iev.value = value;
return write(ev, &iev, sizeof(iev));
}
#else
int push(int ev, unsigned int code, unsigned int value)
{
struct eventHead eh;
struct sockaddr_un servaddr;
int clilen, fd;
const char *errmsg;
/* ev is unused - stupid compiler... */
fd = ev;
/* ignore for now, neutrino does not handle this anyway */
if (value == KEY_RELEASED)
return 0;
memset(&servaddr, 0, sizeof(struct sockaddr_un));
servaddr.sun_family = AF_UNIX;
strncpy(servaddr.sun_path, NEUTRINO_SOCKET, sizeof(servaddr.sun_path) - 1);
clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
perror("cannot open socket " NEUTRINO_SOCKET);
return fd;
}
if (connect(fd, (struct sockaddr *) &servaddr, clilen) < 0)
{
errmsg = "connect " NEUTRINO_SOCKET;
goto error;
}
eh.initiatorID = INITID_GENERIC_INPUT_EVENT_PROVIDER;
eh.eventID = 0; // data field
eh.dataSize = sizeof(int);
#if 0
/* neutrino-hd does not yet do REPEAT or RELEASE AFAICT. */
if (value == KEY_AUTOREPEAT)
code |= 0x0400; // neutrino:CRCInput::RC_repeat
if (value == KEY_RELEASED)
code |= 0x0800; // neutrino:CRCInput::RC_release
#endif
if (write(fd, &eh, sizeof(eh)) < 0)
{
errmsg = "write() eventHead";
goto error;
}
if (write(fd, &code, sizeof(code)) < 0)
{
errmsg = "write() event";
goto error;
}
close(fd);
return 0;
error:
perror(errmsg);
close(fd);
return -1;
}
#endif
int main(int argc, char **argv)
{
int evd;
unsigned long sendcode = KEY_0;
unsigned int keys = sizeof(keyname) / sizeof(struct key);
unsigned long rctime = 0;
unsigned long reptime = 500;
unsigned int offset;
if (argc < 2 || argc > 4)
{
usage(argv[0]);
return 1;
}
if (argc == 2)
if (!strncmp(argv[1], "--help", 6) || !strncmp(argv[1], "-h", 2))
{
usage(argv[0]);
return 1;
}
for (offset = 0; offset < keys; offset++)
{
if (!strcmp(argv[1], keyname[offset].name))
{
sendcode = keyname[offset].code;
break;
}
}
if (offset == keys)
{
printf("keyname '%s' not found in list\n", argv[1]);
return 1;
}
if (argc == 4)
{
reptime = atol(argv[3]);
}
if (argc >= 3)
{
rctime = (atol(argv[2]) * 1000) / reptime;
}
#if defined (EVENTDEV)
evd = open(EVENTDEV, O_RDWR);
if (evd < 0)
{
perror("opening " EVENTDEV " failed");
return 1;
}
#else
evd = -1; // close(-1) does not harm... ;)
#endif
printf("sending key %s for %ld seconds\n", keyname[offset].name, (reptime * rctime) / 1000);
if (push(evd, sendcode, KEY_PRESSED) < 0)
{
perror("writing 'key_pressed' event failed");
close(evd);
return 1;
}
while (rctime--)
{
usleep(reptime * 1000);
if (push(evd, sendcode, KEY_AUTOREPEAT) < 0)
{
perror("writing 'key_autorepeat' event failed");
close(evd);
return 1;
}
}
if (push(evd, sendcode, KEY_RELEASED) < 0)
{
perror("writing 'key_released' event failed");
close(evd);
return 1;
}
close(evd);
return 0;
}