Patch: try to reconnect to lircd

Message ID 1138051905.19370.15.camel@bobcat.mine.nu
State New
Headers

Commit Message

Ville Skyttä Jan. 23, 2006, 9:31 p.m. UTC
  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.
  

Patch

--- vdr-1.3.40/lirc.c.orig	2005-09-02 15:51:35.000000000 +0300
+++ vdr-1.3.40/lirc.c	2006-01-23 22:38:03.000000000 +0200
@@ -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) {
--- vdr-1.3.40/lirc.h.orig	2005-07-31 13:18:15.000000000 +0300
+++ vdr-1.3.40/lirc.h	2006-01-23 22:35:56.000000000 +0200
@@ -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();