2 Copyright 2020 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
26 #include "inputlirc.h"
28 const char* InputLIRC::myModName = "InputLIRC";
30 bool InputLIRC::init()
32 if (initted) return false;
34 log = Log::getInstance();
35 log->log(myModName, Log::DEBUG, "Starting InputLIRC");
39 log->log(myModName, Log::DEBUG, "TCP init error");
45 * Hard code remote keys for now. Put lines like this in inputlirc.conf
46 * The 'THREE' is the VOMP key name, see input.h
47 * remotes["lirc-remote-name"]["lirc-button-name"] = THREE;
49 #include "inputlirc.conf"
54 void InputLIRC::shutdown()
58 remotes.clear(); // FIXME ?
63 bool InputLIRC::start(const std::string& ip, USHORT port)
65 // FIXME implement unix domain socket connection
67 bool tr = tcp.connect(ip, port); // NCONFIG
70 log->log(myModName, Log::DEBUG, "InputLIRC TCP connect failed");
74 threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns
75 listenThread = std::thread( [this]
77 threadStartProtect.lock();
78 threadStartProtect.unlock();
81 threadStartProtect.unlock();
83 log->log(myModName, Log::DEBUG, "InputLIRC command client started");
87 void InputLIRC::stop()
89 std::lock_guard<std::mutex> lg(threadStartProtect); // Also use it to protect against starting while stopping
91 if (!tcp.status()) return;
93 if (listenThread.joinable())
98 threadReqStop = false;
104 void InputLIRC::listenLoop()
110 std::stringstream ss = tcp.readString(&readSuccess, 0);
112 if (threadReqStop) return;
118 log->log(myModName, Log::CRIT, "TCP status fail");
120 } // return to stop this thread
125 log->log(myModName, Log::DEBUG, "got data: %s", ss.str().c_str());
127 std::string remoteName, remoteButton;
129 if (parse(ss.str(), remoteName, remoteButton, repeatCount))
130 log->log(myModName, Log::DEBUG, "Remote: '%s', Button: '%s', Count: '%i'", remoteName.c_str(), remoteButton.c_str(), repeatCount);
132 log->log(myModName, Log::ERR, "Parse error");
137 button = remotes.at(remoteName).at(remoteButton);
139 catch (std::exception& e)
141 log->log(myModName, Log::ERR, "Remote button not found");
145 if (repeatCount == 0) sendInputKey(button);
149 bool InputLIRC::parse(const std::string& input, std::string& remoteName, std::string& remoteButton, int& repeatCount)
152 found = input.find(" ", pos);
153 if (found == std::string::npos) return false;
154 pos = found + 1; // pos at 00
155 found = input.find(" ", pos);
156 if (found == std::string::npos) return false;
157 std::string rcString = input.substr(pos, found - pos);
158 try { repeatCount = std::stoi(rcString, 0, 16); } catch (std::exception& e) { return false; }
159 pos = found + 1; // pos at KE
160 found = input.find(" ", pos);
161 if (found == std::string::npos)
163 remoteButton = input.substr(pos);
166 remoteButton = input.substr(pos, found - pos);
168 if ((input.length() - pos) > 0)
169 remoteName = input.substr(pos);
174 // const char* InputLIRC::getHardCodedHardwareKeyNamesForVompKey(UCHAR /* vompKey */)
179 std::string InputLIRC::getHardwareKeyName(HWC_TYPE /* hardwareKey */)