mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed the RCU remote control handling to avoid problems with NPTL
This commit is contained in:
parent
72759ed131
commit
db35165e25
@ -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 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
|
for pointing out that section filters should only be set if the device actually has
|
||||||
a lock
|
a lock
|
||||||
|
for reporting a lockup with the RCU on NPTL systems
|
||||||
|
|
||||||
Simon Bauschulte <SemiSchwabe@Brutzel.de>
|
Simon Bauschulte <SemiSchwabe@Brutzel.de>
|
||||||
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
||||||
|
4
HISTORY
4
HISTORY
@ -3963,7 +3963,7 @@ Video Disk Recorder Revision History
|
|||||||
commands may now be executed at any time, and the message will be displayed
|
commands may now be executed at any time, and the message will be displayed
|
||||||
(no more "pending message").
|
(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
|
- Fixed handling second audio and Dolby Digital PIDs for encrypted channels
|
||||||
(was broken in version 1.3.37).
|
(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.
|
- 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
|
- 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).
|
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).
|
||||||
|
88
rcu.c
88
rcu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "rcu.h"
|
||||||
@ -23,8 +23,8 @@ cRcuRemote::cRcuRemote(const char *DeviceName)
|
|||||||
dp = 0;
|
dp = 0;
|
||||||
mode = modeB;
|
mode = modeB;
|
||||||
code = 0;
|
code = 0;
|
||||||
numberToSend = -1;
|
number = 0;
|
||||||
lastNumber = 0;
|
data = 0;
|
||||||
receivedCommand = false;
|
receivedCommand = false;
|
||||||
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
@ -32,7 +32,7 @@ cRcuRemote::cRcuRemote(const char *DeviceName)
|
|||||||
cfsetspeed(&t, B9600);
|
cfsetspeed(&t, B9600);
|
||||||
cfmakeraw(&t);
|
cfmakeraw(&t);
|
||||||
if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
|
if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
|
||||||
Number(0);//XXX 8888???
|
SetNumber(8888);
|
||||||
const char *Setup = GetSetup();
|
const char *Setup = GetSetup();
|
||||||
if (Setup) {
|
if (Setup) {
|
||||||
code = *Setup;
|
code = *Setup;
|
||||||
@ -95,13 +95,12 @@ void cRcuRemote::Action(void)
|
|||||||
|
|
||||||
time_t LastCodeRefresh = 0;
|
time_t LastCodeRefresh = 0;
|
||||||
cTimeMs FirstTime;
|
cTimeMs FirstTime;
|
||||||
|
unsigned char LastCode = 0, LastMode = 0;
|
||||||
uint64 LastCommand = 0;
|
uint64 LastCommand = 0;
|
||||||
|
unsigned int LastData = 0;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
|
|
||||||
while (Running() && f >= 0) {
|
while (Running() && f >= 0) {
|
||||||
|
|
||||||
LOCK_THREAD;
|
|
||||||
|
|
||||||
if (ReceiveByte(REPEATLIMIT) == 'X') {
|
if (ReceiveByte(REPEATLIMIT) == 'X') {
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
int b = ReceiveByte();
|
int b = ReceiveByte();
|
||||||
@ -140,11 +139,22 @@ void cRcuRemote::Action(void)
|
|||||||
LastCommand = 0;
|
LastCommand = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LastCommand = 0;
|
unsigned int d = data;
|
||||||
if (numberToSend >= 0) {
|
if (d != LastData) {
|
||||||
Number(numberToSend);
|
SendData(d);
|
||||||
numberToSend = -1;
|
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) {
|
if (code && time(NULL) - LastCodeRefresh > 60) {
|
||||||
SendCommand(code); // in case the PIC listens to the wrong code
|
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)
|
bool cRcuRemote::SendByte(unsigned char c)
|
||||||
{
|
{
|
||||||
LOCK_THREAD;
|
|
||||||
|
|
||||||
for (int retry = 5; retry--;) {
|
for (int retry = 5; retry--;) {
|
||||||
if (SendByteHandshake(c))
|
if (SendByteHandshake(c))
|
||||||
return true;
|
return true;
|
||||||
@ -201,16 +209,24 @@ bool cRcuRemote::SendByte(unsigned char c)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcuRemote::SetCode(unsigned char Code)
|
bool cRcuRemote::SendData(unsigned int n)
|
||||||
{
|
{
|
||||||
code = Code;
|
for (int i = 0; i < 4; i++) {
|
||||||
return SendCommand(code);
|
if (!SendByte(n & 0x7F))
|
||||||
|
return false;
|
||||||
|
n >>= 8;
|
||||||
|
}
|
||||||
|
return SendCommand(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcuRemote::SetMode(unsigned char Mode)
|
void cRcuRemote::SetCode(unsigned char Code)
|
||||||
|
{
|
||||||
|
code = Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRcuRemote::SetMode(unsigned char Mode)
|
||||||
{
|
{
|
||||||
mode = Mode;
|
mode = Mode;
|
||||||
return SendCommand(mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcuRemote::SendCommand(unsigned char Cmd)
|
bool cRcuRemote::SendCommand(unsigned char Cmd)
|
||||||
@ -218,15 +234,9 @@ bool cRcuRemote::SendCommand(unsigned char Cmd)
|
|||||||
return SendByte(Cmd | 0x80);
|
return SendByte(Cmd | 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcuRemote::Digit(int n, int v)
|
void cRcuRemote::SetNumber(int n, bool Hex)
|
||||||
{
|
{
|
||||||
return SendByte(((n & 0x03) << 5) | (v & 0x0F) | (((dp >> n) & 0x01) << 4));
|
number = n;
|
||||||
}
|
|
||||||
|
|
||||||
bool cRcuRemote::Number(int n, bool Hex)
|
|
||||||
{
|
|
||||||
LOCK_THREAD;
|
|
||||||
|
|
||||||
if (!Hex) {
|
if (!Hex) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
sprintf(buf, "%4d", n & 0xFFFF);
|
sprintf(buf, "%4d", n & 0xFFFF);
|
||||||
@ -237,19 +247,17 @@ bool cRcuRemote::Number(int n, bool Hex)
|
|||||||
n = (n << 4) | ((*d - '0') & 0x0F);
|
n = (n << 4) | ((*d - '0') & 0x0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastNumber = n;
|
unsigned int m = 0;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (!Digit(i, n))
|
m <<= 8;
|
||||||
return false;
|
m |= ((i & 0x03) << 5) | (n & 0x0F) | (((dp >> i) & 0x01) << 4);
|
||||||
n >>= 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 ";
|
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
||||||
int n = 0;
|
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)
|
void cRcuRemote::SetPoints(unsigned char Dp, bool On)
|
||||||
@ -271,7 +279,7 @@ void cRcuRemote::SetPoints(unsigned char Dp, bool On)
|
|||||||
dp |= Dp;
|
dp |= Dp;
|
||||||
else
|
else
|
||||||
dp &= ~Dp;
|
dp &= ~Dp;
|
||||||
Number(lastNumber, true);
|
SetNumber(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcuRemote::DetectCode(unsigned char *Code)
|
bool cRcuRemote::DetectCode(unsigned char *Code)
|
||||||
@ -291,12 +299,12 @@ bool cRcuRemote::DetectCode(unsigned char *Code)
|
|||||||
SetMode(modeH);
|
SetMode(modeH);
|
||||||
char buf[5];
|
char buf[5];
|
||||||
sprintf(buf, "C0D%c", *Code);
|
sprintf(buf, "C0D%c", *Code);
|
||||||
String(buf);
|
SetString(buf);
|
||||||
SetCode(*Code);
|
SetCode(*Code);
|
||||||
cCondWait::SleepMs(2 * REPEATDELAY);
|
cCondWait::SleepMs(2 * REPEATDELAY);
|
||||||
if (receivedCommand) {
|
if (receivedCommand) {
|
||||||
SetMode(modeB);
|
SetMode(modeB);
|
||||||
String("----");
|
SetString("----");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (*Code < 'D') {
|
if (*Code < 'D') {
|
||||||
@ -310,10 +318,8 @@ bool cRcuRemote::DetectCode(unsigned char *Code)
|
|||||||
|
|
||||||
void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber)
|
void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber)
|
||||||
{
|
{
|
||||||
if (ChannelNumber && Device->IsPrimaryDevice()) {
|
if (ChannelNumber && Device->IsPrimaryDevice())
|
||||||
LOCK_THREAD;
|
SetNumber(cDevice::CurrentChannel());
|
||||||
numberToSend = cDevice::CurrentChannel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcuRemote::Recording(const cDevice *Device, const char *Name)
|
void cRcuRemote::Recording(const cDevice *Device, const char *Name)
|
||||||
|
16
rcu.h
16
rcu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __RCU_H
|
||||||
@ -19,19 +19,19 @@ private:
|
|||||||
enum { modeH = 'h', modeB = 'b', modeS = 's' };
|
enum { modeH = 'h', modeB = 'b', modeS = 's' };
|
||||||
int f;
|
int f;
|
||||||
unsigned char dp, code, mode;
|
unsigned char dp, code, mode;
|
||||||
int numberToSend;
|
int number;
|
||||||
int lastNumber;
|
unsigned int data;
|
||||||
bool receivedCommand;
|
bool receivedCommand;
|
||||||
bool SendCommand(unsigned char Cmd);
|
bool SendCommand(unsigned char Cmd);
|
||||||
int ReceiveByte(int TimeoutMs = 0);
|
int ReceiveByte(int TimeoutMs = 0);
|
||||||
bool SendByteHandshake(unsigned char c);
|
bool SendByteHandshake(unsigned char c);
|
||||||
bool SendByte(unsigned char c);
|
bool SendByte(unsigned char c);
|
||||||
bool Digit(int n, int v);
|
bool SendData(unsigned int n);
|
||||||
bool SetCode(unsigned char Code);
|
void SetCode(unsigned char Code);
|
||||||
bool SetMode(unsigned char Mode);
|
void SetMode(unsigned char Mode);
|
||||||
bool Number(int n, bool Hex = false);
|
void SetNumber(int n, bool Hex = false);
|
||||||
void SetPoints(unsigned char Dp, bool On);
|
void SetPoints(unsigned char Dp, bool On);
|
||||||
bool String(char *s);
|
void SetString(char *s);
|
||||||
bool DetectCode(unsigned char *Code);
|
bool DetectCode(unsigned char *Code);
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
|
virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
|
||||||
|
Loading…
Reference in New Issue
Block a user