neutrino: add rcsim

This commit is contained in:
Stefan Seyfried
2011-02-06 01:39:54 +01:00
parent 6eae455676
commit 716b1c96b9
4 changed files with 479 additions and 1 deletions

View File

@@ -30,10 +30,12 @@ else
VORBISLIBS = -lvorbisfile -lvorbis -logg VORBISLIBS = -lvorbisfile -lvorbis -logg
endif endif
bin_PROGRAMS = neutrino bin_PROGRAMS = neutrino rcsim
neutrino_SOURCES = neutrino_menue.cpp neutrino.cpp neutrino_SOURCES = neutrino_menue.cpp neutrino.cpp
rcsim_SOURCES = rcsim.c rcsim.h
AM_CPPFLAGS = AM_CPPFLAGS =
if ENABLE_FLAC if ENABLE_FLAC

56
src/create_rcsim_h.sh Normal file
View File

@@ -0,0 +1,56 @@
#!/bin/sh
#
# create a rcsim.h file from the rcinput header
# (C) 2011 Stefan Seyfried
# License: GPL v2
#
# usage: sh ./create_rcsim_h.sh > rcsim.h
cat << EOF
#ifndef KEY_GAMES
#define KEY_GAMES 0x1a1 /* Media Select Games */
#endif
#ifndef KEY_TOPLEFT
#define KEY_TOPLEFT 0x1a2
#endif
#ifndef KEY_TOPRIGHT
#define KEY_TOPRIGHT 0x1a3
#endif
#ifndef KEY_BOTTOMLEFT
#define KEY_BOTTOMLEFT 0x1a4
#endif
#ifndef KEY_BOTTOMRIGHT
#define KEY_BOTTOMRIGHT 0x1a5
#endif
#define KEY_POWERON KEY_FN_F1
#define KEY_POWEROFF KEY_FN_F2
#define KEY_STANDBYON KEY_FN_F3
#define KEY_STANDBYOFF KEY_FN_F4
#define KEY_MUTEON KEY_FN_F5
#define KEY_MUTEOFF KEY_FN_F6
#define KEY_ANALOGON KEY_FN_F7
#define KEY_ANALOGOFF KEY_FN_F8
enum {
EOF
sed -n '/^[[:space:]]*RC_0/,/^[[:space:]]*RC_analog_off/s/^[[:space:]]*/ /p' driver/rcinput.h
cat << EOF
};
struct key{
char *name;
unsigned long code;
};
static const struct key keyname[] = {
EOF
sed -n '/^[[:space:]]*RC_0/,/^[[:space:]]*RC_analog_off/ s/^.*=[[:space:]]*\(KEY_.*\),.*/ { "\1", \1 },/p' driver/rcinput.h
cat << EOF
};
EOF

246
src/rcsim.c Normal file
View File

@@ -0,0 +1,246 @@
/******************************************************************************
* 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 instead
* of the input subsystem for dreambox / tripledragon
* (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>
/* if you want use HAVE_XX_HARDWARE, better include config.h :-) */
#include "config.h"
#ifdef HAVE_DBOX_HARDWARE
#define EVENTDEV "/dev/input/event0"
#else
/* dreambox and tripledragon do not use a "normal" input device, so we cannot
(ab-)use the event repeating function of it. use the neutrino socket instead. */
#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
};
#endif
enum { // not defined in input.h but used like that, at least in 2.4.22
KEY_RELEASED = 0,
KEY_PRESSED,
KEY_AUTOREPEAT
};
#include "rcsim.h"
void usage(char *n){
unsigned int keynum = sizeof(keyname)/sizeof(struct key);
unsigned int i;
printf ("rcsim v1.1\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);
for (i=0;i<keynum;){
if ((i % 4) == 0)
printf ("\n %-16s",keyname[i++].name);
else
printf ("%-16s",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 */
#ifdef HAVE_DBOX_HARDWARE
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;
memset(&servaddr, 0, sizeof(struct sockaddr_un));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, NEUTRINO_SOCKET);
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
#endif
if (value == KEY_RELEASED)
goto out;
// code |= 0x0800; // neutrino:CRCInput::RC_release
if (write(fd, &eh, sizeof(eh)) < 0)
{
errmsg = "write() eventHead";
goto error;
}
if (write(fd, &code, sizeof(code)) < 0)
{
errmsg = "write() event";
goto error;
}
out:
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 time=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){
time=(atol (argv[2])*1000)/reptime;
}
#ifdef HAVE_DBOX_HARDWARE
evd=open (EVENTDEV,O_RDWR);
if (evd<0){
perror ("opening event0 failed");
return 1;
}
#else
evd = -1; // close(-1) does not harm... ;)
#endif
printf ("sending key %s for %ld seconds\n",keyname[offset].name,(reptime*time)/1000);
if (push (evd,sendcode,KEY_PRESSED)<0){
perror ("writing 'key_pressed' event failed");
close (evd);
return 1;
}
while (time--){
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;
}

174
src/rcsim.h Normal file
View File

@@ -0,0 +1,174 @@
#ifndef KEY_GAMES
#define KEY_GAMES 0x1a1 /* Media Select Games */
#endif
#ifndef KEY_TOPLEFT
#define KEY_TOPLEFT 0x1a2
#endif
#ifndef KEY_TOPRIGHT
#define KEY_TOPRIGHT 0x1a3
#endif
#ifndef KEY_BOTTOMLEFT
#define KEY_BOTTOMLEFT 0x1a4
#endif
#ifndef KEY_BOTTOMRIGHT
#define KEY_BOTTOMRIGHT 0x1a5
#endif
#define KEY_POWERON KEY_FN_F1
#define KEY_POWEROFF KEY_FN_F2
#define KEY_STANDBYON KEY_FN_F3
#define KEY_STANDBYOFF KEY_FN_F4
#define KEY_MUTEON KEY_FN_F5
#define KEY_MUTEOFF KEY_FN_F6
#define KEY_ANALOGON KEY_FN_F7
#define KEY_ANALOGOFF KEY_FN_F8
enum {
RC_0 = KEY_0, /* /include/linux/input.h: #define KEY_0 11 */
RC_1 = KEY_1, /* /include/linux/input.h: #define KEY_1 2 */
RC_2 = KEY_2, /* /include/linux/input.h: #define KEY_2 3 */
RC_3 = KEY_3, /* /include/linux/input.h: #define KEY_3 4 */
RC_4 = KEY_4, /* /include/linux/input.h: #define KEY_4 5 */
RC_5 = KEY_5, /* /include/linux/input.h: #define KEY_5 6 */
RC_6 = KEY_6, /* /include/linux/input.h: #define KEY_6 7 */
RC_7 = KEY_7, /* /include/linux/input.h: #define KEY_7 8 */
RC_8 = KEY_8, /* /include/linux/input.h: #define KEY_8 9 */
RC_9 = KEY_9, /* /include/linux/input.h: #define KEY_9 10 */
RC_backspace = KEY_BACKSPACE, /* /include/linux/input.h: #define KEY_BACKSPACE 14 */
RC_up = KEY_UP, /* /include/linux/input.h: #define KEY_UP 103 */
RC_left = KEY_LEFT, /* /include/linux/input.h: #define KEY_LEFT 105 */
RC_right = KEY_RIGHT, /* /include/linux/input.h: #define KEY_RIGHT 106 */
RC_down = KEY_DOWN, /* /include/linux/input.h: #define KEY_DOWN 108 */
RC_spkr = KEY_MUTE, /* /include/linux/input.h: #define KEY_MUTE 113 */
RC_minus = KEY_VOLUMEDOWN, /* /include/linux/input.h: #define KEY_VOLUMEDOWN 114 */
RC_plus = KEY_VOLUMEUP, /* /include/linux/input.h: #define KEY_VOLUMEUP 115 */
RC_standby = KEY_POWER, /* /include/linux/input.h: #define KEY_POWER 116 */
RC_help = KEY_HELP, /* /include/linux/input.h: #define KEY_HELP 138 */
RC_home = KEY_EXIT, /* /include/linux/input.h: #define KEY_HOME 102 */
RC_setup = KEY_MENU, /* /include/linux/input.h: #define KEY_SETUP 141 */
RC_topleft = KEY_TOPLEFT,
RC_topright = KEY_TOPRIGHT,
RC_page_up = KEY_PAGEUP, /* /include/linux/input.h: #define KEY_PAGEUP 104 */
RC_page_down = KEY_PAGEDOWN, /* /include/linux/input.h: #define KEY_PAGEDOWN 109 */
RC_ok = KEY_OK, /* /include/linux/input.h: #define KEY_OK 0x160 */ /* in patched input.h */
RC_red = KEY_RED, /* /include/linux/input.h: #define KEY_RED 0x18e */ /* in patched input.h */
RC_green = KEY_GREEN, /* /include/linux/input.h: #define KEY_GREEN 0x18f */ /* in patched input.h */
RC_yellow = KEY_YELLOW, /* /include/linux/input.h: #define KEY_YELLOW 0x190 */ /* in patched input.h */
RC_blue = KEY_BLUE, /* /include/linux/input.h: #define KEY_BLUE 0x191 */ /* in patched input.h */
RC_top_left = KEY_TOPLEFT, /* /include/linux/input.h: #define KEY_TOPLEFT 0x1a2 */ /* in patched input.h */
RC_top_right = KEY_TOPRIGHT, /* /include/linux/input.h: #define KEY_TOPRIGHT 0x1a3 */ /* in patched input.h */
RC_bottom_left = KEY_BOTTOMLEFT, /* /include/linux/input.h: #define KEY_BOTTOMLEFT 0x1a4 */ /* in patched input.h */
RC_bottom_right = KEY_BOTTOMRIGHT, /* /include/linux/input.h: #define KEY_BOTTOMRIGHT 0x1a5 */ /* in patched input.h */
RC_audio = KEY_AUDIO,
RC_video = KEY_VIDEO,
RC_tv = KEY_TV,
RC_radio = KEY_RADIO,
RC_text = KEY_TEXT,
RC_info = KEY_INFO,
RC_epg = KEY_EPG,
RC_recall = KEY_LAST,
RC_favorites = KEY_FAVORITES,
RC_sat = KEY_SAT,
RC_sat2 = KEY_SAT2,
RC_record = KEY_RECORD,
RC_play = KEY_PLAY,
RC_pause = KEY_PAUSE,
RC_forward = KEY_FORWARD,
RC_rewind = KEY_REWIND,
RC_stop = KEY_STOP,
RC_timeshift = KEY_TIME,
RC_mode = KEY_MODE,
RC_games = KEY_GAMES,
RC_next = KEY_NEXT,
RC_prev = KEY_PREVIOUS,
RC_www = KEY_WWW,
RC_power_on = KEY_POWERON,
RC_power_off = KEY_POWEROFF,
RC_standby_on = KEY_STANDBYON,
RC_standby_off = KEY_STANDBYOFF,
RC_mute_on = KEY_MUTEON,
RC_mute_off = KEY_MUTEOFF,
RC_analog_on = KEY_ANALOGON,
RC_analog_off = KEY_ANALOGOFF,
};
struct key{
char *name;
unsigned long code;
};
static const struct key keyname[] = {
{ "KEY_0", KEY_0 },
{ "KEY_1", KEY_1 },
{ "KEY_2", KEY_2 },
{ "KEY_3", KEY_3 },
{ "KEY_4", KEY_4 },
{ "KEY_5", KEY_5 },
{ "KEY_6", KEY_6 },
{ "KEY_7", KEY_7 },
{ "KEY_8", KEY_8 },
{ "KEY_9", KEY_9 },
{ "KEY_BACKSPACE", KEY_BACKSPACE },
{ "KEY_UP", KEY_UP },
{ "KEY_LEFT", KEY_LEFT },
{ "KEY_RIGHT", KEY_RIGHT },
{ "KEY_DOWN", KEY_DOWN },
{ "KEY_MUTE", KEY_MUTE },
{ "KEY_VOLUMEDOWN", KEY_VOLUMEDOWN },
{ "KEY_VOLUMEUP", KEY_VOLUMEUP },
{ "KEY_POWER", KEY_POWER },
{ "KEY_HELP", KEY_HELP },
{ "KEY_EXIT", KEY_EXIT },
{ "KEY_MENU", KEY_MENU },
{ "KEY_TOPLEFT", KEY_TOPLEFT },
{ "KEY_TOPRIGHT", KEY_TOPRIGHT },
{ "KEY_PAGEUP", KEY_PAGEUP },
{ "KEY_PAGEDOWN", KEY_PAGEDOWN },
{ "KEY_OK", KEY_OK },
{ "KEY_RED", KEY_RED },
{ "KEY_GREEN", KEY_GREEN },
{ "KEY_YELLOW", KEY_YELLOW },
{ "KEY_BLUE", KEY_BLUE },
{ "KEY_TOPLEFT", KEY_TOPLEFT },
{ "KEY_TOPRIGHT", KEY_TOPRIGHT },
{ "KEY_BOTTOMLEFT", KEY_BOTTOMLEFT },
{ "KEY_BOTTOMRIGHT", KEY_BOTTOMRIGHT },
{ "KEY_AUDIO", KEY_AUDIO },
{ "KEY_VIDEO", KEY_VIDEO },
{ "KEY_TV", KEY_TV },
{ "KEY_RADIO", KEY_RADIO },
{ "KEY_TEXT", KEY_TEXT },
{ "KEY_INFO", KEY_INFO },
{ "KEY_EPG", KEY_EPG },
{ "KEY_LAST", KEY_LAST },
{ "KEY_FAVORITES", KEY_FAVORITES },
{ "KEY_SAT", KEY_SAT },
{ "KEY_SAT2", KEY_SAT2 },
{ "KEY_RECORD", KEY_RECORD },
{ "KEY_PLAY", KEY_PLAY },
{ "KEY_PAUSE", KEY_PAUSE },
{ "KEY_FORWARD", KEY_FORWARD },
{ "KEY_REWIND", KEY_REWIND },
{ "KEY_STOP", KEY_STOP },
{ "KEY_TIME", KEY_TIME },
{ "KEY_MODE", KEY_MODE },
{ "KEY_GAMES", KEY_GAMES },
{ "KEY_NEXT", KEY_NEXT },
{ "KEY_PREVIOUS", KEY_PREVIOUS },
{ "KEY_WWW", KEY_WWW },
{ "KEY_POWERON", KEY_POWERON },
{ "KEY_POWEROFF", KEY_POWEROFF },
{ "KEY_STANDBYON", KEY_STANDBYON },
{ "KEY_STANDBYOFF", KEY_STANDBYOFF },
{ "KEY_MUTEON", KEY_MUTEON },
{ "KEY_MUTEOFF", KEY_MUTEOFF },
{ "KEY_ANALOGON", KEY_ANALOGON },
{ "KEY_ANALOGOFF", KEY_ANALOGOFF },
};