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/>.
29 #include "inputlirc.h"
31 const char* InputLIRC::myModName = "InputLIRC";
33 bool InputLIRC::init()
35 if (initted) return false;
37 log = Log::getInstance();
38 log->log(myModName, Log::DEBUG, "Starting InputLIRC");
42 log->log(myModName, Log::DEBUG, "TCP init error");
47 bool arraySuccess = Config::getInstance()->foreachInArray("input_lirc", "remotes", [&] (const std::string& remoteName)
49 log->log(myModName, Log::DEBUG, "Remote name: %s", remoteName.c_str());
52 bool objSuccess = Config::getInstance()->foreachPairInObject("input_lirc", remoteName, [&] (const std::string& lircName, const std::string& vompName)
54 UCHAR keyNumber = InputMan::getVompKeyNumber(vompName.c_str());
56 log->log(myModName, Log::DEBUG, " Lirc: %s, vomp: %s, vomp-number %i", lircName.c_str(), vompName.c_str(), keyNumber);
58 remotes[remoteName][lircName] = keyNumber;
63 log->log(myModName, Log::ERR, "Error reading config for remote %s", remoteName.c_str());
69 log->log(myModName, Log::DEBUG, "Error reading remotes list");
73 log->log(myModName, Log::DEBUG, "Remotes array read OK");
77 using RemotesType = std::map<std::string, std::map<std::string, UCHAR>>;
78 using ButtonsType = std::map<std::string, UCHAR>;
80 for(RemotesType::iterator i = remotes.begin(); i != remotes.end(); i++)
82 ButtonsType& b = i->second;
83 for(ButtonsType:: iterator j = b.begin(); j != b.end(); j++)
85 log->log(myModName, Log::DEBUG, "%s - %s - %i", i->first.c_str(), j->first.c_str(), j->second);
92 void InputLIRC::shutdown()
96 remotes.clear(); // FIXME ?
101 bool InputLIRC::start(const std::string& ip, USHORT port)
103 // FIXME implement unix domain socket connection
105 bool tr = tcp.connect(ip, port); // NCONFIG
108 log->log(myModName, Log::DEBUG, "InputLIRC TCP connect failed");
112 threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns
113 listenThread = std::thread( [this]
115 threadStartProtect.lock();
116 threadStartProtect.unlock();
119 threadStartProtect.unlock();
121 log->log(myModName, Log::DEBUG, "InputLIRC command client started");
125 void InputLIRC::stop()
127 std::lock_guard<std::mutex> lg(threadStartProtect); // Also use it to protect against starting while stopping
129 if (!tcp.status()) return;
131 if (listenThread.joinable())
133 threadReqStop = true;
136 threadReqStop = false;
142 void InputLIRC::listenLoop()
148 std::stringstream ss = tcp.readString(&readSuccess, 0);
150 if (threadReqStop) return;
156 log->log(myModName, Log::CRIT, "TCP status fail");
158 } // return to stop this thread
163 log->log(myModName, Log::DEBUG, "got data: %s", ss.str().c_str());
165 std::string remoteName, remoteButton;
167 if (parse(ss.str(), remoteName, remoteButton, repeatCount))
168 log->log(myModName, Log::DEBUG, "Remote: '%s', Button: '%s', Count: '%i'", remoteName.c_str(), remoteButton.c_str(), repeatCount);
170 log->log(myModName, Log::ERR, "Parse error");
175 button = remotes.at(remoteName).at(remoteButton);
177 catch (std::exception& e)
179 log->log(myModName, Log::ERR, "Remote button not found");
183 if (repeatCount == 0) sendInputKey(button);
187 bool InputLIRC::parse(const std::string& input, std::string& remoteName, std::string& remoteButton, int& repeatCount)
190 found = input.find(" ", pos);
191 if (found == std::string::npos) return false;
192 pos = found + 1; // pos at 00
193 found = input.find(" ", pos);
194 if (found == std::string::npos) return false;
195 std::string rcString = input.substr(pos, found - pos);
196 try { repeatCount = std::stoi(rcString, 0, 16); } catch (std::exception& e) { return false; }
197 pos = found + 1; // pos at KE
198 found = input.find(" ", pos);
199 if (found == std::string::npos)
201 remoteButton = input.substr(pos);
204 remoteButton = input.substr(pos, found - pos);
206 if ((input.length() - pos) > 0)
207 remoteName = input.substr(pos);
212 // const char* InputLIRC::getHardCodedHardwareKeyNamesForVompKey(UCHAR /* vompKey */)
217 std::string InputLIRC::getHardwareKeyName(HWC_TYPE /* hardwareKey */)