cec : stop the processor thread and delete the CSerialPort instance on exit. zzzz
[deb_libcec.git] / src / testclient / main.cpp
CommitLineData
abbca718
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
33#include "../../include/CECExports.h"
b9187cc6 34#include "../lib/platform/threads.h"
abbca718
LOK
35#include "../lib/util/StdString.h"
36#include <cstdio>
37#include <fcntl.h>
38#include <iostream>
39#include <string>
b9187cc6 40#include <sstream>
abbca718
LOK
41
42using namespace CEC;
43using namespace std;
44
390b42d6 45#define CEC_TEST_CLIENT_VERSION 3
abbca718 46
b9187cc6
LOK
47
48inline bool HexStrToInt(const std::string& data, int& value)
49{
50 return sscanf(data.c_str(), "%x", &value) == 1;
51}
52
53
54//get the first word (separated by whitespace) from string data and place that in word
55//then remove that word from string data
56bool GetWord(string& data, string& word)
57{
58 stringstream datastream(data);
59 string end;
60
61 datastream >> word;
62 if (datastream.fail())
63 {
64 data.clear();
65 return false;
66 }
67
68 size_t pos = data.find(word) + word.length();
69
70 if (pos >= data.length())
71 {
72 data.clear();
73 return true;
74 }
75
76 data = data.substr(pos);
77
78 datastream.clear();
79 datastream.str(data);
80
81 datastream >> end;
82 if (datastream.fail())
83 data.clear();
84
85 return true;
86}
87
2abe74eb 88void flush_log(ICECAdapter *cecParser)
abbca718
LOK
89{
90 cec_log_message message;
91 while (cecParser && cecParser->GetNextLogMessage(&message))
92 {
93 switch (message.level)
94 {
95 case CEC_LOG_ERROR:
96 cout << "ERROR: " << message.message.c_str() << endl;
97 break;
98 case CEC_LOG_WARNING:
99 cout << "WARNING: " << message.message.c_str() << endl;
100 break;
101 case CEC_LOG_NOTICE:
102 cout << "NOTICE: " << message.message.c_str() << endl;
103 break;
104 case CEC_LOG_DEBUG:
105 cout << "DEBUG: " << message.message.c_str() << endl;
106 break;
107 }
108 }
109}
110
2abe74eb 111void list_devices(ICECAdapter *parser)
abbca718
LOK
112{
113 cout << "Found devices: ";
2abe74eb
LOK
114 vector<cec_adapter> devices;
115 int iDevicesFound = parser->FindAdapters(devices);
abbca718
LOK
116 if (iDevicesFound <= 0)
117 {
118#ifdef __WINDOWS__
119 cout << "Not supported yet, sorry!" << endl;
120#else
121 cout << "NONE" << endl;
122#endif
123 }
124 else
125 {
126 cout << devices.size() << endl;
127 for (unsigned int iDevicePtr = 0; iDevicePtr < devices.size(); iDevicePtr++)
128 {
129 CStdString strDevice;
130 strDevice.Format("device: %d\npath: %s\ncom port: %s", iDevicePtr, devices[iDevicePtr].path.c_str(), devices[0].comm.c_str());
131 cout << endl << strDevice.c_str() << endl;
132 }
133 }
134}
135
136void show_help(const char* strExec)
137{
138 cout << endl <<
139 strExec << " {-h|--help|-l|--list-devices|[COM PORT]}" << endl <<
140 endl <<
141 "parameters:" << endl <<
142 "\t-h --help Shows this help text" << endl <<
143 "\t-l --list-devices List all devices on this system" << endl <<
825ddb96
LOK
144 "\t[COM PORT] The com port to connect to. If no COM port is given, the client tries to connect to the first device that is detected" << endl <<
145 endl <<
146 "Type 'h' or 'help' and press enter after starting the client to display all available commands" << endl;
147}
148
149void show_console_help(void)
150{
151 cout << endl <<
152 "================================================================================" << endl <<
153 "Available commands:" << endl <<
154 endl <<
155 "tx {bytes} transfer bytes over the CEC line." << endl <<
156 "[tx 40 00 FF 11 22 33] sends bytes 0x40 0x00 0xFF 0x11 0x22 0x33" << endl <<
157 endl <<
825ddb96
LOK
158 "la {logical_address} change the logical address of the CEC adapter." << endl <<
159 "[la 4] logical address 4" << endl <<
160 endl <<
161 "[ping] send a ping command to the CEC adapter." << endl <<
162 "[bl] to let the adapter enter the bootloader, to upgrade the flash rom." << endl <<
163 "[h] or [help] show this help." << endl <<
164 "[q] or [quit] to quit the CEC test client and switch off all connected CEC devices." << endl <<
165 "================================================================================" << endl;
abbca718
LOK
166}
167
168int main (int argc, char *argv[])
169{
2abe74eb 170 ICECAdapter *parser = LoadLibCec("CEC Tester");
abbca718
LOK
171 if (!parser && parser->GetMinVersion() > CEC_TEST_CLIENT_VERSION)
172 {
173 cout << "Unable to create parser. Is libcec.dll present?" << endl;
174 return 1;
175 }
176 CStdString strLog;
177 strLog.Format("CEC Parser created - libcec version %d", parser->GetLibVersion());
178 cout << strLog.c_str() << endl;
179
180 //make stdin non-blocking
181#ifndef __WINDOWS__
182 int flags = fcntl(0, F_GETFL, 0);
183 flags |= O_NONBLOCK;
184 fcntl(0, F_SETFL, flags);
185#endif
186
187 string strPort;
188 if (argc < 2)
189 {
190 cout << "no serial port given. trying autodetect: ";
2abe74eb
LOK
191 vector<cec_adapter> devices;
192 int iDevicesFound = parser->FindAdapters(devices);
abbca718
LOK
193 if (iDevicesFound <= 0)
194 {
195 cout << "FAILED" << endl;
196 UnloadLibCec(parser);
197 return 1;
198 }
199 else
200 {
201 cout << endl << " path: " << devices[0].path << endl <<
202 " com port: " << devices[0].comm << endl << endl;
203 strPort = devices[0].comm;
204 }
205 }
206 else if (!strcmp(argv[1], "--list-devices") || !strcmp(argv[1], "-l"))
207 {
208 list_devices(parser);
209 UnloadLibCec(parser);
210 return 0;
211 }
212 else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
213 {
214 show_help(argv[0]);
215 return 0;
216 }
217 else
218 {
219 strPort = argv[1];
220 }
221
222 if (!parser->Open(strPort.c_str()))
223 {
224 cout << "unable to open the device on port " << strPort << endl;
225 flush_log(parser);
226 UnloadLibCec(parser);
227 return 1;
228 }
229
230 cout << "cec device opened" << endl;
231 usleep(CEC_SETTLE_DOWN_TIME);
232
8829d291 233 parser->PowerOnDevices(CECDEVICE_TV);
abbca718
LOK
234 flush_log(parser);
235
236 parser->SetActiveView();
237 flush_log(parser);
238
239 bool bContinue(true);
240 cout << "waiting for input" << endl;
241 while (bContinue)
242 {
243 flush_log(parser);
244
245 string input;
246 getline(cin, input);
247 cin.clear();
248
249 if (!input.empty())
250 {
251 string command;
252 if (GetWord(input, command))
253 {
254 if (command == "tx")
255 {
256 string strvalue;
257 int ivalue;
258 vector<uint8_t> bytes;
259 while (GetWord(input, strvalue) && HexStrToInt(strvalue, ivalue))
260 bytes.push_back(ivalue);
261
262 parser->Transmit(bytes);
263 }
6dfe9213
LOK
264 else if (command == "la")
265 {
266 string strvalue;
6dfe9213
LOK
267 if (GetWord(input, strvalue))
268 {
269 parser->SetLogicalAddress((cec_logical_address) atoi(strvalue.c_str()));
abbca718
LOK
270 }
271 }
272 else if (command == "ping")
273 {
2abe74eb 274 parser->PingAdapter();
abbca718
LOK
275 }
276 else if (command == "bl")
277 {
278 parser->StartBootloader();
279 }
825ddb96
LOK
280 else if (command == "h" || command == "help")
281 {
282 show_console_help();
283 }
abbca718
LOK
284 else if (command == "q" || command == "quit")
285 {
286 bContinue = false;
287 }
288 }
289 if (bContinue)
290 cout << "waiting for input" << endl;
291 }
292 CCondition::Sleep(50);
293 }
294
2abe74eb 295 parser->StandbyDevices(CECDEVICE_BROADCAST);
5f39c4d8 296 parser->Close();
abbca718
LOK
297 flush_log(parser);
298 UnloadLibCec(parser);
299 return 0;
300}