]> git.vomp.tv Git - vompclient.git/commitdiff
Implement unix sockets in Input classes
authorChris Tallon <chris@vomp.tv>
Tue, 7 Sep 2021 16:17:27 +0000 (17:17 +0100)
committerChris Tallon <chris@vomp.tv>
Tue, 7 Sep 2021 16:17:27 +0000 (17:17 +0100)
config.json.sample
inputlirc.cc
inputlirc.h
inputman.cc
remotelirc.cc [deleted file]
remotelirc.h [deleted file]
tcp.cc
tcp.h
vdpc.cc

index 72cbab18ceb4ea79b981e0cac2a959a99af0f2d7..6148411f86eb5ef813e34b6d2630fe29e8f6eb58 100644 (file)
   {
     // input_lirc has no defaults
 
-    "lirc_ip": "192.0.2.0",
-    "lirc_port": 8765,
+    // Use these two options:
+
+        "lirc_ip": "192.0.2.0",  /* Numeric IPv4 or IPv6 */
+        "lirc_port": 8765,       /* except this, this has a default */
+
+    // Or this one:
+
+        "lirc_socket": "/run/lirc/lircd",
+
+    //
+
+    // List all the Lirc remote names to listen to here:
 
     "remotes": [ "lirc-remote-name-1", "lirc-remote-name-2" ],
 
+    // Now create a section here for each Lirc remote. Map each Lirc button to vomp keys.
+
     "lirc-remote-name-1":
     {
+      /* List all keys to be used by Vomp
+      On the left - the Lirc key name. On the right - the Vomp key name. See input.h (for now)  */
+
       "KEY_POWER": "POWER",
       "KEY_MUTE": "MUTE"
-      /* etc. List all keys to be used by Vomp
-      On the left - the Lirc key name. On the right - the Vomp key name. See input.h (for now)  */
+      // etc.
     },
 
     "lirc-remote-name-2":
index af72f660c284f8aab72ee86d0ad64c41a995ec4b..c112ece1589bf472d6cf14ec11a6f86d077276e3 100644 (file)
@@ -100,14 +100,36 @@ void InputLIRC::shutdown()
   initted = false;
 }
 
-bool InputLIRC::start(const std::string& ip, USHORT port)
+bool InputLIRC::start()
 {
-  // FIXME implement unix domain socket connection
+  log->debug(TAG, "Start called");
+
+
+
+  std::string lircIP;
+  bool checkA = Config::getInstance()->getString("input_lirc", "lirc_ip", lircIP);
+  int lircPort = 8765;
+  bool checkB = Config::getInstance()->getInt("input_lirc", "lirc_port", lircPort);
+  std::string lircSocket;
+  bool checkC = Config::getInstance()->getString("input_lirc", "lirc_socket", lircSocket);
+
+  bool tr{};
+
+  // Prefer socket
+  if (checkC)
+  {
+    LogNT::getInstance()->info(TAG, "Starting with unix socket: {}", lircSocket);
+    tr = tcp.connectSocket(lircSocket);
+  }
+  else if (checkA) // If no checkC, must be checkA
+  {
+    LogNT::getInstance()->info(TAG, "Starting with IP: {} {}", lircIP, lircPort);
+    tr = tcp.connect(lircIP, lircPort);
+  }
 
-  bool tr = tcp.connect(ip, port); // NCONFIG
   if (!tr)
   {
-    log->debug(TAG, "InputLIRC TCP connect failed");
+    log->debug(TAG, "TCP connect failed");
     return false;
   }
 
@@ -120,7 +142,7 @@ bool InputLIRC::start(const std::string& ip, USHORT port)
   });
   threadStartProtect.unlock();
 
-  log->debug(TAG, "InputLIRC command client started");
+  log->debug(TAG, "Started");
   return true;
 }
 
@@ -182,6 +204,7 @@ void InputLIRC::listenLoop()
       continue;
     }
     
+    log->debug(TAG, "Submitting vomp key: '{}'", button);
     if (repeatCount == 0) sendInputKey(button);
   }
 }
index 39be337042032989e98093f2a43afc52cde2c742..7b6e224e06865239554f40fee83e95584dfc4a42 100644 (file)
@@ -38,7 +38,7 @@ class InputLIRC : public Input
     void shutdown();
 
     using Input::start; // Bring all start()s from base class so our start doesn't generate compile warnings
-    bool start(const std::string& ip, USHORT port);
+    bool start();
     void stop();
 
     void InitHWCListwithDefaults() {};
index 6e52aacf075920068332b90f209cc00bf2618d16..c7088f05c1b37f14736fb1dd55e61568d2656317 100644 (file)
@@ -135,31 +135,7 @@ bool InputMan::start()
 
   if (inputUDP && inputUDP->start()) oneOK = true;
 
-  if (inputLirc)
-  {
-    std::string lircIP;
-    bool checkA = Config::getInstance()->getString("input", "lirc_ip", lircIP);
-    int lircPort = 8765;
-    bool checkB = Config::getInstance()->getInt("input", "lirc_port", lircPort);
-
-    if (!checkA || !checkB)
-    {
-      delete inputLirc;
-      inputLirc = NULL;
-    }
-    else
-    {
-      if (inputLirc->start(lircIP, lircPort))
-      {
-        oneOK = true;
-      }
-      else
-      {
-        delete inputLirc;
-        inputLirc = NULL;
-      }
-    }
-  }
+  if (inputLirc && inputLirc->start()) oneOK = true;
 
   if (!oneOK)
     LogNT::getInstance()->crit(TAG, "InputMan could not start any input module");
diff --git a/remotelirc.cc b/remotelirc.cc
deleted file mode 100644 (file)
index 60268f3..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-    Copyright 2004-2005 Chris Tallon 2009 Marten Richter
-
-    This file is part of VOMP.
-
-    VOMP is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    VOMP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with VOMP; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*/
-#include <sys/socket.h>
-
-#include "remotelirc.h"
-#include "i18n.h"
-
-#include "oldlog.h"
-
-#define LIRC_BUFFER_SIZE  128 
-
-
-RemoteLirc::RemoteLirc()
-{
-  if (instance) return;
-  initted = 0;
-  tv.tv_sec = 0;
-  tv.tv_usec = 0;
-  device = -1;
-}
-
-RemoteLirc::~RemoteLirc()
-{
-}
-
-int RemoteLirc::init(char* devName)
-{
-  if (initted) return 0;
-  initted = 1;
-
-  address.sun_family = AF_UNIX;
-
-  strcpy(address.sun_path, devName);
-  if (!sockConnect()) return 0;
-/*
-  device = open(devName, O_RDONLY);
-  if (device < 0)
-  {
-    initted = 0;
-    return 0;
-  }
-*/
-  return 1;
-}
-
-int RemoteLirc::shutdown()
-{
-  if (!initted) return 0;
-  initted = 0;
-  close(device);
-  device = 0;
-  return 1;
-}
-
-int RemoteLirc::sockConnect()
-{
-        if ((device = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
-                if (connect(device, (struct sockaddr *)&address, sizeof(address)) >= 0)
-                        return 1;
-                Log::getInstance()->log("Remote", Log::INFO, "Connecting lircd failed %s", address.sun_path);
-                close(device);
-                device = -1;
-        }
-        else
-               Log::getInstance()->log("Remote", Log::INFO, "Creating socket failed");
-        
-     Log::getInstance()->log("Remote", Log::DEBUG, "Creating socket successfull");
-
-        return 0;
-}
-
-int RemoteLirc::getDevice()
-{
-  if (!initted) return 0;
-  return device;
-}
-
-UCHAR RemoteLirc::getButtonPress(int waitType)
-{
-  /* how = 0 - block
-     how = 1 - start new wait
-     how = 2 - continue wait
-     how = 3 - no wait
-  */
-
-  unsigned long input;
-  struct timeval* passToSelect = NULL;
-  char buffer[LIRC_BUFFER_SIZE]; 
-  int retval;
-  fd_set readfds;
-
-  if (waitType == 0)
-  {
-    passToSelect = NULL;
-  }
-  else if (waitType == 1)
-  {
-    tv.tv_sec = 1;
-    tv.tv_usec = 000000;
-    passToSelect = &tv;
-  }
-  else if (waitType == 2)
-  {
-    if ((tv.tv_sec == 0) && (tv.tv_usec == 0))  // protection in case timer = 0
-    {
-      tv.tv_sec = 1;
-      tv.tv_usec = 000000;
-    }
-    passToSelect = &tv;
-  }
-  else if (waitType == 3)
-  {
-    tv.tv_sec = 0;
-    tv.tv_usec = 0;
-    passToSelect = &tv;
-  }
-  FD_ZERO(&readfds);
-  FD_SET(device, &readfds);
-
-  retval = select(device + 1, &readfds, NULL, NULL, &tv);
-  // 0 = nothing happened
-  // 1 = data arrived (actually num of descriptors that changed)
-  // other value = signal or error
-  if (retval == 0) return NA_NONE;
-  if (retval == -1) return NA_SIGNAL;
-  
-  int count = read(device, &buffer, sizeof(LIRC_BUFFER_SIZE));
-  if (count  > 0)
-  {
-         int input=NA_UNKNOWN;
-         if (sscanf(buffer, "%d", &input) != 1) { 
-                 Log::getInstance()->log("Remote", Log::DEBUG, "ERROR: unparseable lirc command: %s", buffer);
-                 return NA_UNKNOWN;
-      }
-
-         Log::getInstance()->log("Remote", Log::DEBUG, "Button %x", input);
-
-         return (UCHAR) TranslateHWC(input);
-  }
-  return NA_UNKNOWN;
-}
-
-void RemoteLirc::clearBuffer()
-{
-//  while(getButtonPress(3) != NA_NONE);
-}
-
-UCHAR RemoteLirc::TranslateHWCFixed(ULLONG code)
-{
-    switch (code) 
-    {
-    case 0xa9:
-        return DOWN;
-    case 0xa8:
-        return UP;
-    case 0xaa:
-        return LEFT;
-    case 0xab:
-        return RIGHT;
-    case 0x09:
-        return MENU;
-    case 0x8d:
-        return BACK;
-    case 0x0d:
-        return OK;
-    case 0xd2:
-        return POWER;
-    default:
-        return NA_UNKNOWN;
-    };
-}
-
-
-void RemoteLirc::InitHWCListwithDefaults()
-{
-  translist[0x9e] = VOLUMEUP;
-  translist[0x9f] = VOLUMEDOWN;
-  translist[0x94] = CHANNELUP;
-  translist[0x90] = CHANNELDOWN;
-
-  // Common buttons
-  translist[0xf1] = ZERO;
-  translist[0xf2] = ONE;
-  translist[0xf3] = TWO;
-  translist[0xf4] = THREE;
-  translist[0xf5] = FOUR;
-  translist[0xf6] = FIVE;
-  translist[0xf7] = SIX;
-  translist[0xf8] = SEVEN;
-  translist[0xf9] = EIGHT;
-  translist[0xfa] = NINE;
-  translist[0xd2] = POWER;
-  translist[0x91] = GO;
-  translist[0xde] = RED;
-  translist[0xdf] = GREEN;
-  translist[0xe0] = YELLOW;
-  translist[0xe2] = BLUE;
-
-  translist[0xe1] = MUTE;
-  translist[0xd5] = REVERSE;
-  translist[0xd6] = FORWARD;
-  translist[0x1b] = STOP;
-  translist[0xea] = PAUSE;
-  translist[0xe9] = PLAY;
-  translist[0xdb] = SKIPBACK;
-  translist[0xdc] = SKIPFORWARD;
-
-  // Old remote only
-  translist[0xda] = FULL;
-
-}
-
-
-char* RemoteLirc::HCWDesc(ULLONG hcw)
-{
-   
-    char *ret=NULL;
-
-       ret=new char[20];
-
-    switch(hcw)
-    {
-       case  0x01: strncpy(ret,tr("Suspend") ,20);break;
-       case  0x09: strncpy(ret,tr("Menu") ,20);break;
-       case  0x0d: strncpy(ret,tr("Enter") ,20);break;
-       case  0x1b: strncpy(ret,tr("Stop") ,20);break;
-       case  0x8A: strncpy(ret,tr("TV mode") ,20);break;
-       case  0x8c: strncpy(ret,tr("Setup") ,20);break;
-       case  0x8D: strncpy(ret,tr("Return") ,20);break;
-       case  0x90: strncpy(ret,tr("Repeat") ,20);break;
-       case  0x91: strncpy(ret,tr("Time Seek"),20);break;
-       case  0x94: strncpy(ret,tr("Title") ,20);break;
-       case  0x95: strncpy(ret,tr("Info") ,20);break;
-       case  0x9e: strncpy(ret,tr("Volume up") ,20);break;
-       case  0x9f: strncpy(ret,tr("Volume down") ,20);break;
-       case  0xa8: strncpy(ret,tr("up") ,20);break;
-       case  0xaa: strncpy(ret,tr("Left") ,20);break;
-       case  0xab: strncpy(ret,tr("Right") ,20);break;
-       case  0xa9: strncpy(ret,tr("Down") ,20);break;
-       case  0xd0: strncpy(ret,tr("Home") ,20);break;
-       case  0xd2: strncpy(ret,tr("Stand by") ,20);break;
-       case  0xd5: strncpy(ret,tr("Backward") ,20);break;
-       case  0xd6: strncpy(ret,tr("Forward") ,20);break;
-       case  0xd8: strncpy(ret,tr("Audio") ,20);break;
-       case  0xd9: strncpy(ret,tr("Slow") ,20);break;
-       case  0xda: strncpy(ret,tr("Zoom") ,20);break;
-       case  0xdb: strncpy(ret,tr("Previous") ,20);break;
-    case  0xde: strncpy(ret,tr("Red") ,20);break;
-       case  0xdc: strncpy(ret,tr("Next") ,20);break;
-       case  0xdf: strncpy(ret,tr("Green") ,20);break;
-    case  0xe0: strncpy(ret,tr("Yellow") ,20);break;
-       case  0xe1: strncpy(ret,tr("Mute") ,20);break;
-       case  0xe2: strncpy(ret,tr("Blue") ,20);break;
-       case  0xe9: strncpy(ret,tr("Play") ,20);break;
-       case  0xea: strncpy(ret,tr("Pause") ,20);break;
-       case  0xeb: strncpy(ret,tr("Subtitle") ,20);break;
-       case  0xec: strncpy(ret,tr("Angle") ,20);break;
-       case  0xef: strncpy(ret,tr("Eject") ,20);break;
-       case  0xf1: strncpy(ret,tr("0") ,20);break;
-       case  0xf2: strncpy(ret,tr("1") ,20);break;
-       case  0xf3: strncpy(ret,tr("2") ,20);break;
-       case  0xf4: strncpy(ret,tr("3") ,20);break;
-       case  0xf5: strncpy(ret,tr("4") ,20);break;
-       case  0xf6: strncpy(ret,tr("5") ,20);break;
-       case  0xf7: strncpy(ret,tr("6") ,20);break;
-       case  0xf8: strncpy(ret,tr("7") ,20);break;
-       case  0xf9: strncpy(ret,tr("8") ,20);break;
-       case  0xfA: strncpy(ret,tr("9") ,20);break;
-       case  0xFC: strncpy(ret,tr("Caps") ,20);break;
-       case  0xFD: strncpy(ret,tr("File mode") ,20);break;
-   
-    
-    default:{
-        ULONG ri=(ULONG)hcw;
-        sprintf(ret,"R: %X",ri);
-                  }break;
-    };
-    return ret;
-}
diff --git a/remotelirc.h b/remotelirc.h
deleted file mode 100644 (file)
index 44f4fdb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-    Copyright 2004-2005 Chris Tallon 2009 Marten Richter
-    Inspired from code from vdr by Klaus Schmidinger
-
-    This file is part of VOMP.
-
-    VOMP is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    VOMP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with VOMP; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*/
-
-#ifndef REMOTELIRC_H
-#define REMOTELIRC_H
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/un.h>
-
-#include "input.h"
-#include "defines.h"
-
-class RemoteLirc : public Remote
-{
-  public:
-    RemoteLirc();
-    ~RemoteLirc();
-
-    int init(char *devName);
-    int shutdown();
-    int getDevice();
-    UCHAR getButtonPress(int how);
-    void clearBuffer();
-       int sockConnect();
-
-       virtual void InitHWCListwithDefaults();
-    virtual char* HCWDesc(ULLONG hcw);
-
-  private:
-    
-    virtual UCHAR TranslateHWCFixed(ULLONG code);
-         
-       int initted;
-    int device;
-
-       struct sockaddr_un address;
-    struct timeval tv;
-};
-
-#endif
diff --git a/tcp.cc b/tcp.cc
index a002c47802869044569e602bcf431be1556324ff..38d570032b6d9f1664ec6955d7255416f6f08d42 100644 (file)
--- a/tcp.cc
+++ b/tcp.cc
@@ -31,6 +31,7 @@
   #include <linux/if_packet.h> // for getMAC
   #include <net/ethernet.h> // for getMAC
   #include <ifaddrs.h> // getifaddrs
+  #include <sys/un.h>  // uds
 #endif
 
 #include <sys/types.h>  // socket connect getaddrinfo
@@ -86,6 +87,34 @@ bool TCP::init()
   return true;
 }
 
+#ifndef WIN32
+bool TCP::connectSocket(const std::string& socketFile)
+{
+  if (connected) return false;
+
+  int pathLength = strlen(socketFile.c_str()); // Specifically use strlen rather than std::string length stuff
+  if (pathLength > 107) { logger->crit(TAG, "socket name too long"); return false; }
+
+  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (sockfd == -1) { logger->crit(TAG, "socket error"); return false; }
+
+  fcntl(sockfd, F_SETFL, O_NONBLOCK);
+
+  struct sockaddr_un uds;
+  uds.sun_family = AF_UNIX;
+  strcpy(uds.sun_path, socketFile.c_str());
+  int connectResult = ::connect(sockfd, (struct sockaddr *)&uds, pathLength + sizeof(uds.sun_family));
+
+  if (connectResult == 0) // success
+  {
+    connected = true;
+    return true;
+  }
+
+  return waitForConnect(connectResult);
+}
+#endif
+
 bool TCP::connect(const std::string& ip, USHORT port)
 {
   if (connected) return false;
@@ -121,13 +150,19 @@ bool TCP::connect(const std::string& ip, USHORT port)
   // There should only be one aip result..
   int connectResult = ::connect(sockfd, aip->ai_addr, aip->ai_addrlen);
 
+  freeaddrinfo(aip);
+
   if (connectResult == 0) // success
   {
-    freeaddrinfo(aip);
     connected = true;
     return true;
   }
 
+  return waitForConnect(connectResult);
+}
+
+bool TCP::waitForConnect(int connectResult)
+{
 #ifdef WIN32
   if ((connectResult != SOCKET_ERROR) || (WSAGetLastError() != WSAEWOULDBLOCK))
 #else
@@ -176,7 +211,6 @@ bool TCP::connect(const std::string& ip, USHORT port)
 
   if ((selectResult == 1) || FD_ISSET(sockfd, &writefds))
   {
-    freeaddrinfo(aip);
     logger->info(TAG, "Connected");
     connected = true;
     return true;
diff --git a/tcp.h b/tcp.h
index 65931a5e5f091690bdebd9484d878ccec6ef3108..680e9db0b14565650c51b21e13cca604371efd06 100644 (file)
--- a/tcp.h
+++ b/tcp.h
@@ -44,6 +44,10 @@ class TCP
     void abortCall(); // causes a read/connect call to immediately abort
 
     bool connect(const std::string& ip, USHORT port);
+#ifndef WIN32
+    bool connectSocket(const std::string& socketFile);
+#endif
+
     bool read(void* dest, ULONG numBytes, int timeoutSec = 2); // Set timeoutSec to 0 for no timeout
     std::stringstream readString(bool* result, int timeoutSec = 2);
     bool write(void* src, ULONG numBytes);
@@ -62,6 +66,8 @@ class TCP
     int recStringBufStart{};
     int recStringBufUsed{};
 
+    bool waitForConnect(int connectResult);
+
 #ifdef WIN32
     SOCKET abortSocket;
 #else
diff --git a/vdpc.cc b/vdpc.cc
index 3d60d7863d8a3d98272f1dba2c9fd427b38d620c..573b5acaa15bb105a9914fad398a23e9a66baf7b 100644 (file)
--- a/vdpc.cc
+++ b/vdpc.cc
@@ -242,7 +242,7 @@ void VDPC::VDPC4::threadMethod()
       }
     }
 
-    logger->debug("VDPC4", "loop stopnow = %i", stopNow);
+    logger->debug("VDPC4", "loop stopnow = {}", stopNow);
   }
 }