Patch: try to reconnect to lircd
Commit Message
Here's a patch that makes VDR try to reconnect to lircd if the
connection is lost (eg. due to lircd restart on package upgrade, or
whatever). The delay could be longer than the default of 3 seconds in
this patch, no strong opinions on that.
It would be cool to periodically try it also if the lircd connection is
not available when starting VDR, but I think that's less often needed.
@@ -12,29 +12,22 @@
#include "lirc.h"
#include <netinet/in.h>
#include <sys/socket.h>
-#include <sys/un.h>
#define REPEATLIMIT 20 // ms
#define REPEATDELAY 350 // ms
#define KEYPRESSDELAY 150 // ms
+#define RECONNECTDELAY 3000 // ms
cLircRemote::cLircRemote(const char *DeviceName)
:cRemote("LIRC")
,cThread("LIRC remote control")
{
- struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, DeviceName);
- if ((f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
- if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0) {
- Start();
- return;
- }
- LOG_ERROR_STR(DeviceName);
- close(f);
+ if (Connect()) {
+ Start();
+ return;
}
- else
- LOG_ERROR_STR(DeviceName);
f = -1;
}
@@ -47,6 +40,20 @@
close(fh);
}
+bool cLircRemote::Connect(void)
+{
+ if ((f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
+ if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0)
+ return true;
+ LOG_ERROR_STR(addr.sun_path);
+ close(f);
+ f = -1;
+ }
+ else
+ LOG_ERROR_STR(addr.sun_path);
+ return false;
+}
+
bool cLircRemote::Ready(void)
{
return f >= 0;
@@ -67,10 +74,16 @@
int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
if (ready && ret <= 0 ) {
- esyslog("ERROR: lircd connection lost");
+ esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", (float) RECONNECTDELAY/1000);
close(f);
f = -1;
- break;
+ while (Running() && f < 0) {
+ cCondWait::SleepMs(RECONNECTDELAY);
+ if (Connect()) {
+ isyslog("reconnected to lircd");
+ break;
+ }
+ }
}
if (ready && ret > 21) {
@@ -12,12 +12,15 @@
#include "remote.h"
#include "thread.h"
+#include <sys/un.h>
class cLircRemote : public cRemote, private cThread {
private:
enum { LIRC_KEY_BUF = 30, LIRC_BUFFER_SIZE = 128 };
int f;
+ struct sockaddr_un addr;
virtual void Action(void);
+ virtual bool Connect(void);
public:
cLircRemote(const char *DeviceName);
virtual ~cLircRemote();