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 static const char* TAG = "InputLIRC";
33 const char* InputLIRC::myModName = "InputLIRC";
35 bool InputLIRC::init()
37 if (initted) return false;
39 log = LogNT::getInstance();
40 log->debug(TAG, "Starting InputLIRC");
44 log->debug(TAG, "TCP init error");
49 bool arraySuccess = Config::getInstance()->foreachInArray("input_lirc", "remotes", [&] (const std::string& remoteName)
51 log->debug(TAG, "Remote name: {}", remoteName);
54 bool objSuccess = Config::getInstance()->foreachPairInObject("input_lirc", remoteName, [&] (const std::string& lircName, const std::string& vompName)
56 UCHAR keyNumber = InputMan::getVompKeyNumber(vompName.c_str());
58 log->debug(TAG, " Lirc: {}, vomp: {}, vomp-number {}", lircName, vompName, keyNumber);
60 remotes[remoteName][lircName] = keyNumber;
65 log->error(TAG, "Error reading config for remote {}", remoteName);
71 log->debug(TAG, "Error reading remotes list");
75 log->debug(TAG, "Remotes array read OK");
79 using RemotesType = std::map<std::string, std::map<std::string, UCHAR>>;
80 using ButtonsType = std::map<std::string, UCHAR>;
82 for(RemotesType::iterator i = remotes.begin(); i != remotes.end(); i++)
84 ButtonsType& b = i->second;
85 for(ButtonsType:: iterator j = b.begin(); j != b.end(); j++)
87 log->debug(TAG, "{} - {} - {}", i->first.c_str(), j->first.c_str(), j->second);
94 void InputLIRC::shutdown()
98 remotes.clear(); // FIXME ?
103 bool InputLIRC::start(const std::string& ip, USHORT port)
105 // FIXME implement unix domain socket connection
107 bool tr = tcp.connect(ip, port); // NCONFIG
110 log->debug(TAG, "InputLIRC TCP connect failed");
114 threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns
115 listenThread = std::thread( [this]
117 threadStartProtect.lock();
118 threadStartProtect.unlock();
121 threadStartProtect.unlock();
123 log->debug(TAG, "InputLIRC command client started");
127 void InputLIRC::stop()
129 std::lock_guard<std::mutex> lg(threadStartProtect); // Also use it to protect against starting while stopping
131 if (!tcp.status()) return;
133 if (listenThread.joinable())
135 threadReqStop = true;
138 threadReqStop = false;
144 void InputLIRC::listenLoop()
150 std::stringstream ss = tcp.readString(&readSuccess, 0);
152 if (threadReqStop) return;
158 log->crit(TAG, "TCP status fail");
160 } // return to stop this thread
165 log->debug(TAG, "got data: {}", ss.str());
167 std::string remoteName, remoteButton;
169 if (parse(ss.str(), remoteName, remoteButton, repeatCount))
170 log->debug(TAG, "Remote: '{}', Button: '{}', Count: '{}'", remoteName, remoteButton, repeatCount);
172 log->error(TAG, "Parse error");
177 button = remotes.at(remoteName).at(remoteButton);
179 catch (std::exception& e)
181 log->error(TAG, "Remote button not found");
185 if (repeatCount == 0) sendInputKey(button);
189 bool InputLIRC::parse(const std::string& input, std::string& remoteName, std::string& remoteButton, int& repeatCount)
192 found = input.find(" ", pos);
193 if (found == std::string::npos) return false;
194 pos = found + 1; // pos at 00
195 found = input.find(" ", pos);
196 if (found == std::string::npos) return false;
197 std::string rcString = input.substr(pos, found - pos);
198 try { repeatCount = std::stoi(rcString, 0, 16); } catch (std::exception& e) { return false; }
199 pos = found + 1; // pos at KE
200 found = input.find(" ", pos);
201 if (found == std::string::npos)
203 remoteButton = input.substr(pos);
206 remoteButton = input.substr(pos, found - pos);
208 if ((input.length() - pos) > 0)
209 remoteName = input.substr(pos);
214 // const char* InputLIRC::getHardCodedHardwareKeyNamesForVompKey(UCHAR /* vompKey */)
219 std::string InputLIRC::getHardwareKeyName(HWC_TYPE /* hardwareKey */)