13#include <linux/version.h>
14#define HAVE_KERNEL_LIRC (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
16#include <netinet/in.h>
17#include <sys/socket.h>
21#include <linux/lirc.h>
25#define RECONNECTDELAY 3000
32 virtual void Action(
void)
override;
40 virtual void Action(
void)
override;
43 bool Connect(
const char *DeviceName);
79 addr.sun_family = AF_UNIX;
87 if ((
f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
88 if (connect(
f, (
struct sockaddr *)&
addr,
sizeof(
addr)) >= 0)
111 bool pressed =
false;
118 int ret = ready ?
safe_read(
f, buf,
sizeof(buf)) : -1;
120 if (
f < 0 || ready && ret <= 0) {
121 esyslog(
"ERROR: lircd connection broken, trying to reconnect every %.1f seconds",
float(
RECONNECTDELAY) / 1000);
128 isyslog(
"reconnected to lircd");
134 if (ready && ret > 0) {
138 if (sscanf(buf,
"%*x %x %29s", &count, KeyName) != 2) {
139 esyslog(
"ERROR: unparsable lirc command: %s", buf);
142 int Delta = ThisTime.
Elapsed();
145 if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.
Elapsed() < (uint)
Setup.RcRepeatDelay)
148 Put(LastKeyName,
false,
true);
149 strn0cpy(LastKeyName, KeyName,
sizeof(LastKeyName));
155 else if (FirstTime.
Elapsed() < (uint)
Setup.RcRepeatDelay)
157 else if (LastTime.
Elapsed() < (uint)
Setup.RcRepeatDelta)
162 timeout = Delta * 3 / 2;
166 Put(KeyName, repeat);
170 if (pressed && repeat)
171 Put(LastKeyName,
false,
true);
185 unsigned mode = LIRC_MODE_SCANCODE;
186 f = open(DeviceName, O_RDONLY, 0);
197 else if (ioctl(
f, LIRC_SET_REC_MODE, &mode)) {
216 uint64_t FirstTime = 0, LastTime = 0;
217 uint32_t LastKeyCode = 0;
218 uint16_t LastFlags =
false;
219 bool SeenRepeat =
false;
224 ssize_t ret = read(
f, &sc,
sizeof sc);
226 if (ret ==
sizeof sc) {
227 const bool SameKey = sc.keycode == LastKeyCode && !((sc.flags ^ LastFlags) & LIRC_SCANCODE_FLAG_TOGGLE);
229 if (sc.flags & LIRC_SCANCODE_FLAG_REPEAT != 0)
233 if (SameKey && uint((sc.timestamp - FirstTime) / 1000000) < uint(
Setup.RcRepeatDelay))
236 if (!SameKey || (SeenRepeat && !(sc.flags & LIRC_SCANCODE_FLAG_REPEAT))) {
239 Put(LastKeyCode,
false,
true);
241 FirstTime = sc.timestamp;
242 LastKeyCode = sc.keycode;
243 LastFlags = sc.flags;
245 else if (uint((sc.timestamp - LastTime) / 1000000) < uint(
Setup.RcRepeatDelta))
250 LastTime = sc.timestamp;
251 Put(sc.keycode, repeat);
255 Put(LastKeyCode,
false,
true);
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
static bool FileReady(int FileDes, int TimeoutMs=1000)
virtual void Action(void) override
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
bool Connect(const char *DeviceName)
virtual ~cLircRemote() override
virtual bool Ready(void) override
static void NewLircRemote(const char *Name)
cLircRemote(const char *Name)
cLircUsrRemote(const char *DeviceName)
virtual void Action(void) override
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
cRemote(const char *Name)
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
cThread(const char *Description=NULL, bool LowPriority=false)
Creates a new thread.
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
uint64_t Elapsed(void) const
void Set(int Ms=0)
Sets the timer.