diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2005-12-16 14:53:58 +0100 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2005-12-16 14:53:58 +0100 |
commit | db35165e25974df8719d253cde398831877c526d (patch) | |
tree | 19ebb537f3870623910448072da6b0730f225c56 | |
parent | 72759ed1313982aaade3a380fe5beddfffc7824b (diff) | |
download | vdr-db35165e25974df8719d253cde398831877c526d.tar.gz vdr-db35165e25974df8719d253cde398831877c526d.tar.bz2 |
Fixed the RCU remote control handling to avoid problems with NPTL
-rw-r--r-- | CONTRIBUTORS | 1 | ||||
-rw-r--r-- | HISTORY | 4 | ||||
-rw-r--r-- | rcu.c | 86 | ||||
-rw-r--r-- | rcu.h | 16 |
4 files changed, 58 insertions, 49 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6904d22f..1da9a259 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -310,6 +310,7 @@ Andreas Share <a.share@t-online.de> for his support in keeping the Premiere World channels up to date in 'channels.conf' for pointing out that section filters should only be set if the device actually has a lock + for reporting a lockup with the RCU on NPTL systems Simon Bauschulte <SemiSchwabe@Brutzel.de> for his support in keeping the Premiere World channels up to date in 'channels.conf' @@ -3963,7 +3963,7 @@ Video Disk Recorder Revision History commands may now be executed at any time, and the message will be displayed (no more "pending message"). -2005-12-11: Version 1.3.38 +2005-12-16: Version 1.3.38 - Fixed handling second audio and Dolby Digital PIDs for encrypted channels (was broken in version 1.3.37). @@ -3974,3 +3974,5 @@ Video Disk Recorder Revision History - Limited the frequency of log messages from the cRepackers. - Now using the gettid() syscall to get a thread's pid, so that we get a useful value on NPTL systems (suggested by Johannes Stezenbach). +- Fixed the RCU remote control handling to avoid problems with NPTL (thanks + to Andreas Share for reporting a lockup with the RCU on NPTL systems). @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: rcu.c 1.10 2005/08/15 12:30:21 kls Exp $ + * $Id: rcu.c 1.11 2005/12/16 14:43:37 kls Exp $ */ #include "rcu.h" @@ -23,8 +23,8 @@ cRcuRemote::cRcuRemote(const char *DeviceName) dp = 0; mode = modeB; code = 0; - numberToSend = -1; - lastNumber = 0; + number = 0; + data = 0; receivedCommand = false; if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) { struct termios t; @@ -32,7 +32,7 @@ cRcuRemote::cRcuRemote(const char *DeviceName) cfsetspeed(&t, B9600); cfmakeraw(&t); if (tcsetattr(f, TCSAFLUSH, &t) == 0) { - Number(0);//XXX 8888??? + SetNumber(8888); const char *Setup = GetSetup(); if (Setup) { code = *Setup; @@ -95,13 +95,12 @@ void cRcuRemote::Action(void) time_t LastCodeRefresh = 0; cTimeMs FirstTime; + unsigned char LastCode = 0, LastMode = 0; uint64 LastCommand = 0; + unsigned int LastData = 0; bool repeat = false; while (Running() && f >= 0) { - - LOCK_THREAD; - if (ReceiveByte(REPEATLIMIT) == 'X') { for (int i = 0; i < 6; i++) { int b = ReceiveByte(); @@ -140,11 +139,22 @@ void cRcuRemote::Action(void) LastCommand = 0; } else { - LastCommand = 0; - if (numberToSend >= 0) { - Number(numberToSend); - numberToSend = -1; + 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 (code && time(NULL) - LastCodeRefresh > 60) { SendCommand(code); // in case the PIC listens to the wrong code @@ -192,8 +202,6 @@ bool cRcuRemote::SendByteHandshake(unsigned char c) bool cRcuRemote::SendByte(unsigned char c) { - LOCK_THREAD; - for (int retry = 5; retry--;) { if (SendByteHandshake(c)) return true; @@ -201,16 +209,24 @@ bool cRcuRemote::SendByte(unsigned char c) return false; } -bool cRcuRemote::SetCode(unsigned char Code) +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; - return SendCommand(code); } -bool cRcuRemote::SetMode(unsigned char Mode) +void cRcuRemote::SetMode(unsigned char Mode) { mode = Mode; - return SendCommand(mode); } bool cRcuRemote::SendCommand(unsigned char Cmd) @@ -218,15 +234,9 @@ bool cRcuRemote::SendCommand(unsigned char Cmd) return SendByte(Cmd | 0x80); } -bool cRcuRemote::Digit(int n, int v) -{ - return SendByte(((n & 0x03) << 5) | (v & 0x0F) | (((dp >> n) & 0x01) << 4)); -} - -bool cRcuRemote::Number(int n, bool Hex) +void cRcuRemote::SetNumber(int n, bool Hex) { - LOCK_THREAD; - + number = n; if (!Hex) { char buf[8]; sprintf(buf, "%4d", n & 0xFFFF); @@ -237,19 +247,17 @@ bool cRcuRemote::Number(int n, bool Hex) n = (n << 4) | ((*d - '0') & 0x0F); } } - lastNumber = n; + unsigned int m = 0; for (int i = 0; i < 4; i++) { - if (!Digit(i, n)) - return false; + m <<= 8; + m |= ((i & 0x03) << 5) | (n & 0x0F) | (((dp >> i) & 0x01) << 4); n >>= 4; } - return SendCommand(mode); + data = m; } -bool cRcuRemote::String(char *s) +void cRcuRemote::SetString(char *s) { - LOCK_THREAD; - const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP "; int n = 0; @@ -262,7 +270,7 @@ bool cRcuRemote::String(char *s) } } } - return Number(n, true); + SetNumber(n, true); } void cRcuRemote::SetPoints(unsigned char Dp, bool On) @@ -271,7 +279,7 @@ void cRcuRemote::SetPoints(unsigned char Dp, bool On) dp |= Dp; else dp &= ~Dp; - Number(lastNumber, true); + SetNumber(number); } bool cRcuRemote::DetectCode(unsigned char *Code) @@ -291,12 +299,12 @@ bool cRcuRemote::DetectCode(unsigned char *Code) SetMode(modeH); char buf[5]; sprintf(buf, "C0D%c", *Code); - String(buf); + SetString(buf); SetCode(*Code); cCondWait::SleepMs(2 * REPEATDELAY); if (receivedCommand) { SetMode(modeB); - String("----"); + SetString("----"); return true; } if (*Code < 'D') { @@ -310,10 +318,8 @@ bool cRcuRemote::DetectCode(unsigned char *Code) void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber) { - if (ChannelNumber && Device->IsPrimaryDevice()) { - LOCK_THREAD; - numberToSend = cDevice::CurrentChannel(); - } + if (ChannelNumber && Device->IsPrimaryDevice()) + SetNumber(cDevice::CurrentChannel()); } void cRcuRemote::Recording(const cDevice *Device, const char *Name) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: rcu.h 1.4 2005/07/31 10:18:00 kls Exp $ + * $Id: rcu.h 1.5 2005/12/16 14:21:20 kls Exp $ */ #ifndef __RCU_H @@ -19,19 +19,19 @@ private: enum { modeH = 'h', modeB = 'b', modeS = 's' }; int f; unsigned char dp, code, mode; - int numberToSend; - int lastNumber; + int number; + unsigned int data; bool receivedCommand; bool SendCommand(unsigned char Cmd); int ReceiveByte(int TimeoutMs = 0); bool SendByteHandshake(unsigned char c); bool SendByte(unsigned char c); - bool Digit(int n, int v); - bool SetCode(unsigned char Code); - bool SetMode(unsigned char Mode); - bool Number(int n, bool Hex = false); + bool SendData(unsigned int n); + void SetCode(unsigned char Code); + void SetMode(unsigned char Mode); + void SetNumber(int n, bool Hex = false); void SetPoints(unsigned char Dp, bool On); - bool String(char *s); + void SetString(char *s); bool DetectCode(unsigned char *Code); virtual void Action(void); virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber); |