summaryrefslogtreecommitdiff
path: root/rcu.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <Klaus (dot) Schmidinger (at) tvdr (dot) de>2012-03-10 16:18:00 +0100
committerDieter Hametner <dh (plus) vdr (at) gekrumbel (dot) de>2012-03-11 18:00:38 +0100
commit5117f359388e50d2ad46ba53330741c6b1a1e7ae (patch)
tree9400497309cc2e919ae81c3b06de90ca2e3377b2 /rcu.c
parent3df1b6d1397379a7ccdde4b559d46baf3f515837 (diff)
downloadvdr-patches-5117f359388e50d2ad46ba53330741c6b1a1e7ae.tar.gz
vdr-patches-5117f359388e50d2ad46ba53330741c6b1a1e7ae.tar.bz2
Version 1.7.26
Original announce message: VDR developer version 1.7.26 is now available at ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.26.tar.bz2 A 'diff' against the previous version is available at ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.25-1.7.26.diff MD5 checksums: eb57398e44935ecb0bfc532bdfead312 vdr-1.7.26.tar.bz2 62e0f39e2c53ec2b5abd3ebb0e00ce3d vdr-1.7.25-1.7.26.diff WARNING: ======== This is a developer version. Even though I use it in my productive environment. I strongly recommend that you only use it under controlled conditions and for testing and debugging. From the HISTORY file: - Now checking for NULL in cOsd::AddPixmap() (suggested by Christoph Haubrich). - Fixed the German translation of "VDR will shut down in %s minutes" (thanks to Frank Neumann). - The replay progress display is now turned on whenever a mark is toggled (not only when one is set). - Toggling a mark now restarts the timeout of the replay progress display. - Fixed a possible race condition with the SVDRP commands CLRE and PUTE, where EPG data from the transponder could be handled even though it shouldn't be handled for 10 seconds. - Added some missing member initializations in cBitmap. - Improved displaying the play mode in the ST:TNG skin. - Made the ST:TNG skin the default in case the user selected skin is not available. - Improved displaying signal strength and quality in the ST:TNG skin's channel display. - Fixed switching devices to the transponders of VPS recordings in case there are only bonded devices. The cDevice's "avoid device" mechanism has been replaced by using "occupied". - Fixed selecting devices for the EPG scan in case the primary device is bonded with an other one. - Removed the calls to EITScanner.UsesDevice(this) from dvb[hs]ddevice.c, because the code following these calls is only executed if LiveView is true, which is never the case when the EITScanner switches to a channel. - Removed the obsolete function cEITScanner::UsesDevice(). If a plugin has used this function to find out whether a call to its cStatus::ChannelSwitch() function was due to a live channel switch, it can use that function's new parameter LiveView. Any plugins that implement cStatus::ChannelSwitch() need to add the parameter 'bool LiveView' to that function. - Fixed parsing channel data in case the audio pid is 0. On channels that only broadcast Dolby Digital audio there were sometimes log entries like "changing pids of channel ... from ... to ..." with no apparent difference between the old and new set of pids. - Fixed checking pids in case a channel has only Dolby Digital audio. - The Green button in the "Edit timer" menu can now be used to toggle between single shot and repeating timers. This is the same as pressing '0' when the "Day" field is selected, but it works at any time (and is more obvious). - Revoked "If the first event in a schedule has a table id of 0x00, any incoming EIT data for that schedule from the DVB stream will be completely ignored". - Added a new plugin interface for implementing EPG handlers. + A plugin can implement an EPG handler by creating an object derived from cEpgHandler and implementing the necessary member functions. + The special handling of events with table id 0x00 has been dropped. For backwards compatibility EPG events with table ids lower than 0x4E will be treated as if they had a table id of 0x4E, and the new plugin 'epgtableid0' can be used to have them handled like in previous versions. + The default table id for a newly created cEvent has been changed to 0xFF, which is higher than any normal table id that is broadcast in the EIT data. See PLUGINS.html, section "Electronic Program Guide" for more information.
Diffstat (limited to 'rcu.c')
-rw-r--r--rcu.c329
1 files changed, 0 insertions, 329 deletions
diff --git a/rcu.c b/rcu.c
deleted file mode 100644
index 2e20314..0000000
--- a/rcu.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * rcu.c: RCU remote control
- *
- * See the main source file 'vdr.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rcu.c 2.0 2007/08/24 13:15:48 kls Exp $
- */
-
-#include "rcu.h"
-#include <netinet/in.h>
-#include <termios.h>
-#include <unistd.h>
-#include "tools.h"
-
-#define REPEATLIMIT 150 // ms
-#define REPEATDELAY 350 // ms
-#define HANDSHAKETIMEOUT 20 // ms
-
-cRcuRemote::cRcuRemote(const char *DeviceName)
-:cRemote("RCU")
-,cThread("RCU remote control")
-{
- dp = 0;
- mode = modeB;
- code = 0;
- number = 0;
- data = 0;
- receivedCommand = false;
- if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
- struct termios t;
- if (tcgetattr(f, &t) == 0) {
- cfsetspeed(&t, B9600);
- cfmakeraw(&t);
- if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
- SetNumber(8888);
- const char *Setup = GetSetup();
- if (Setup) {
- code = *Setup;
- SetCode(code);
- isyslog("connecting to %s remote control using code %c", Name(), code);
- }
- Start();
- return;
- }
- }
- LOG_ERROR_STR(DeviceName);
- close(f);
- }
- else
- LOG_ERROR_STR(DeviceName);
- f = -1;
-}
-
-cRcuRemote::~cRcuRemote()
-{
- Cancel();
-}
-
-bool cRcuRemote::Ready(void)
-{
- return f >= 0;
-}
-
-bool cRcuRemote::Initialize(void)
-{
- if (f >= 0) {
- unsigned char Code = '0';
- isyslog("trying codes for %s remote control...", Name());
- for (;;) {
- if (DetectCode(&Code)) {
- code = Code;
- break;
- }
- }
- isyslog("established connection to %s remote control using code %c", Name(), code);
- char buffer[16];
- snprintf(buffer, sizeof(buffer), "%c", code);
- PutSetup(buffer);
- return true;
- }
- return false;
-}
-
-void cRcuRemote::Action(void)
-{
-#pragma pack(1)
- union {
- struct {
- unsigned short address;
- unsigned int command;
- } data;
- unsigned char raw[6];
- } buffer;
-#pragma pack()
-
- time_t LastCodeRefresh = 0;
- cTimeMs FirstTime;
- unsigned char LastCode = 0, LastMode = 0;
- uint64_t LastCommand = ~0; // 0x00 might be a valid command
- unsigned int LastData = 0;
- bool repeat = false;
-
- while (Running() && f >= 0) {
- if (ReceiveByte(REPEATLIMIT) == 'X') {
- for (int i = 0; i < 6; i++) {
- int b = ReceiveByte();
- if (b >= 0) {
- buffer.raw[i] = b;
- if (i == 5) {
- unsigned short Address = ntohs(buffer.data.address); // the PIC sends bytes in "network order"
- uint64_t Command = ntohl(buffer.data.command);
- if (code == 'B' && Address == 0x0000 && Command == 0x00004000)
- // Well, well, if it isn't the "d-box"...
- // This remote control sends the above command before and after
- // each keypress - let's just drop this:
- break;
- Command |= uint64_t(Address) << 32;
- if (Command != LastCommand) {
- LastCommand = Command;
- repeat = false;
- FirstTime.Set();
- }
- else {
- if (FirstTime.Elapsed() < REPEATDELAY)
- break; // repeat function kicks in after a short delay
- repeat = true;
- }
- Put(Command, repeat);
- receivedCommand = true;
- }
- }
- else
- break;
- }
- }
- else if (repeat) { // the last one was a repeat, so let's generate a release
- Put(LastCommand, false, true);
- repeat = false;
- LastCommand = ~0;
- }
- else {
- unsigned int d = data;
- if (d != LastData) {
- SendData(d);
- LastData = d;
- }
- unsigned char c = code;
- if (c != LastCode) {
- SendCommand(c);
- LastCode = c;
- }
- unsigned char m = mode;
- if (m != LastMode) {
- SendCommand(m);
- LastMode = m;
- }
- LastCommand = ~0;
- }
- if (!repeat && code && time(NULL) - LastCodeRefresh > 60) {
- SendCommand(code); // in case the PIC listens to the wrong code
- LastCodeRefresh = time(NULL);
- }
- }
-}
-
-int cRcuRemote::ReceiveByte(int TimeoutMs)
-{
- // Returns the byte if one was received within a timeout, -1 otherwise
- if (cFile::FileReady(f, TimeoutMs)) {
- unsigned char b;
- if (safe_read(f, &b, 1) == 1)
- return b;
- else
- LOG_ERROR;
- }
- return -1;
-}
-
-bool cRcuRemote::SendByteHandshake(unsigned char c)
-{
- if (f >= 0) {
- int w = write(f, &c, 1);
- if (w == 1) {
- for (int reply = ReceiveByte(HANDSHAKETIMEOUT); reply >= 0;) {
- if (reply == c)
- return true;
- else if (reply == 'X') {
- // skip any incoming RC code - it will come again
- for (int i = 6; i--;) {
- if (ReceiveByte() < 0)
- return false;
- }
- }
- else
- return false;
- }
- }
- LOG_ERROR;
- }
- return false;
-}
-
-bool cRcuRemote::SendByte(unsigned char c)
-{
- for (int retry = 5; retry--;) {
- if (SendByteHandshake(c))
- return true;
- }
- return false;
-}
-
-bool cRcuRemote::SendData(unsigned int n)
-{
- for (int i = 0; i < 4; i++) {
- if (!SendByte(n & 0x7F))
- return false;
- n >>= 8;
- }
- return SendCommand(mode);
-}
-
-void cRcuRemote::SetCode(unsigned char Code)
-{
- code = Code;
-}
-
-void cRcuRemote::SetMode(unsigned char Mode)
-{
- mode = Mode;
-}
-
-bool cRcuRemote::SendCommand(unsigned char Cmd)
-{
- return SendByte(Cmd | 0x80);
-}
-
-void cRcuRemote::SetNumber(int n, bool Hex)
-{
- number = n;
- if (!Hex) {
- char buf[8];
- sprintf(buf, "%4d", n & 0xFFFF);
- n = 0;
- for (char *d = buf; *d; d++) {
- if (*d == ' ')
- *d = 0xF;
- n = (n << 4) | ((*d - '0') & 0x0F);
- }
- }
- unsigned int m = 0;
- for (int i = 0; i < 4; i++) {
- m <<= 8;
- m |= ((i & 0x03) << 5) | (n & 0x0F) | (((dp >> i) & 0x01) << 4);
- n >>= 4;
- }
- data = m;
-}
-
-void cRcuRemote::SetString(const char *s)
-{
- const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
- int n = 0;
-
- for (int i = 0; *s && i < 4; s++, i++) {
- n <<= 4;
- for (const char *c = chars; *c; c++) {
- if (*c == *s) {
- n |= c - chars;
- break;
- }
- }
- }
- SetNumber(n, true);
-}
-
-void cRcuRemote::SetPoints(unsigned char Dp, bool On)
-{
- if (On)
- dp |= Dp;
- else
- dp &= ~Dp;
- SetNumber(number);
-}
-
-bool cRcuRemote::DetectCode(unsigned char *Code)
-{
- // Caller should initialize 'Code' to 0 and call DetectCode()
- // until it returns true. Whenever DetectCode() returns false
- // and 'Code' is not 0, the caller can use 'Code' to display
- // a message like "Trying code '%c'". If false is returned and
- // 'Code' is 0, all possible codes have been tried and the caller
- // can either stop calling DetectCode() (and give some error
- // message), or start all over again.
- if (*Code < 'A' || *Code > 'D') {
- *Code = 'A';
- return false;
- }
- if (*Code <= 'D') {
- SetMode(modeH);
- char buf[5];
- sprintf(buf, "C0D%c", *Code);
- SetString(buf);
- SetCode(*Code);
- cCondWait::SleepMs(2 * REPEATDELAY);
- if (receivedCommand) {
- SetMode(modeB);
- SetString("----");
- return true;
- }
- if (*Code < 'D') {
- (*Code)++;
- return false;
- }
- }
- *Code = 0;
- return false;
-}
-
-void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber)
-{
- if (ChannelNumber && Device->IsPrimaryDevice())
- SetNumber(cDevice::CurrentChannel());
-}
-
-void cRcuRemote::Recording(const cDevice *Device, const char *Name, const char *FileName, bool On)
-{
- SetPoints(1 << Device->DeviceNumber(), Device->Receiving());
-}