vdr 2.6.1
lirc.c
Go to the documentation of this file.
1/*
2 * lirc.c: LIRC remote control
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
8 *
9 * $Id: lirc.c 4.2 2020/09/16 13:48:33 kls Exp $
10 */
11
12#include "lirc.h"
13#include <netinet/in.h>
14#include <sys/socket.h>
15
16#define RECONNECTDELAY 3000 // ms
17
18cLircRemote::cLircRemote(const char *DeviceName)
19:cRemote("LIRC")
20,cThread("LIRC remote control")
21{
22 addr.sun_family = AF_UNIX;
23 strn0cpy(addr.sun_path, DeviceName, sizeof(addr.sun_path));
24 if (!Connect())
25 f = -1;
26 Start();
27}
28
30{
31 int fh = f;
32 f = -1;
33 Cancel();
34 if (fh >= 0)
35 close(fh);
36}
37
39{
40 if ((f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
41 if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0)
42 return true;
43 LOG_ERROR_STR(addr.sun_path);
44 close(f);
45 f = -1;
46 }
47 else
48 LOG_ERROR_STR(addr.sun_path);
49 return false;
50}
51
53{
54 return f >= 0;
55}
56
58{
59 cTimeMs FirstTime;
60 cTimeMs LastTime;
61 cTimeMs ThisTime;
62 char buf[LIRC_BUFFER_SIZE];
63 char LastKeyName[LIRC_KEY_BUF] = "";
64 bool pressed = false;
65 bool repeat = false;
66 int timeout = -1;
67
68 while (Running()) {
69
70 bool ready = f >= 0 && cFile::FileReady(f, timeout);
71 int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
72
73 if (f < 0 || ready && ret <= 0) {
74 esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(RECONNECTDELAY) / 1000);
75 if (f >= 0)
76 close(f);
77 f = -1;
78 while (Running() && f < 0) {
80 if (Connect()) {
81 isyslog("reconnected to lircd");
82 break;
83 }
84 }
85 }
86
87 if (ready && ret > 0) {
88 buf[ret - 1] = 0;
89 int count;
90 char KeyName[LIRC_KEY_BUF];
91 if (sscanf(buf, "%*x %x %29s", &count, KeyName) != 2) { // '29' in '%29s' is LIRC_KEY_BUF-1!
92 esyslog("ERROR: unparsable lirc command: %s", buf);
93 continue;
94 }
95 int Delta = ThisTime.Elapsed(); // the time between two subsequent LIRC events
96 ThisTime.Set();
97 if (count == 0) { // new key pressed
98 if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (uint)Setup.RcRepeatDelay)
99 continue; // skip keys coming in too fast
100 if (repeat)
101 Put(LastKeyName, false, true); // generated release for previous repeated key
102 strn0cpy(LastKeyName, KeyName, sizeof(LastKeyName));
103 pressed = true;
104 repeat = false;
105 FirstTime.Set();
106 timeout = -1;
107 }
108 else if (FirstTime.Elapsed() < (uint)Setup.RcRepeatDelay)
109 continue; // repeat function kicks in after a short delay
110 else if (LastTime.Elapsed() < (uint)Setup.RcRepeatDelta)
111 continue; // skip same keys coming in too fast
112 else {
113 pressed = true;
114 repeat = true;
115 timeout = Delta * 3 / 2;
116 }
117 if (pressed) {
118 LastTime.Set();
119 Put(KeyName, repeat);
120 }
121 }
122 else {
123 if (pressed && repeat) // the last one was a repeat, so let's generate a release
124 Put(LastKeyName, false, true);
125 pressed = false;
126 repeat = false;
127 *LastKeyName = 0;
128 timeout = -1;
129 }
130 }
131}
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
Definition: thread.c:72
static bool FileReady(int FileDes, int TimeoutMs=1000)
Definition: tools.c:1722
struct sockaddr_un addr
virtual ~cLircRemote()
Definition: lirc.c:29
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
Definition: lirc.c:57
virtual bool Ready(void)
Definition: lirc.c:52
cLircRemote(const char *DeviceName)
Definition: lirc.c:18
bool Connect(void)
Definition: lirc.c:38
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
Definition: remote.c:124
int RcRepeatDelay
Definition: config.h:307
int RcRepeatDelta
Definition: config.h:308
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
Definition: thread.c:304
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
Definition: thread.c:354
uint64_t Elapsed(void) const
Definition: tools.c:802
void Set(int Ms=0)
Sets the timer.
Definition: tools.c:792
cSetup Setup
Definition: config.c:372
#define LOG_ERROR_STR(s)
ssize_t safe_read(int filedes, void *buffer, size_t size)
Definition: tools.c:53
#define esyslog(a...)
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
#define isyslog(a...)
#define RECONNECTDELAY
Definition: lirc.c:16