added changelog for release v0.3
[deb_libcec.git] / src / testclient / main.cpp
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"
34 #include "../lib/util/threads.h"
35 #include "../lib/util/misc.h"
36 #include "../lib/util/StdString.h"
37 #include <cstdio>
38 #include <fcntl.h>
39 #include <iostream>
40 #include <string>
41
42 using namespace CEC;
43 using namespace std;
44
45 #define CEC_TEST_CLIENT_VERSION 2
46
47 void flush_log(ICECDevice *cecParser)
48 {
49 cec_log_message message;
50 while (cecParser && cecParser->GetNextLogMessage(&message))
51 {
52 switch (message.level)
53 {
54 case CEC_LOG_ERROR:
55 cout << "ERROR: " << message.message.c_str() << endl;
56 break;
57 case CEC_LOG_WARNING:
58 cout << "WARNING: " << message.message.c_str() << endl;
59 break;
60 case CEC_LOG_NOTICE:
61 cout << "NOTICE: " << message.message.c_str() << endl;
62 break;
63 case CEC_LOG_DEBUG:
64 cout << "DEBUG: " << message.message.c_str() << endl;
65 break;
66 }
67 }
68 }
69
70 void list_devices(ICECDevice *parser)
71 {
72 cout << "Found devices: ";
73 vector<cec_device> devices;
74 int iDevicesFound = parser->FindDevices(devices);
75 if (iDevicesFound <= 0)
76 {
77 #ifdef __WINDOWS__
78 cout << "Not supported yet, sorry!" << endl;
79 #else
80 cout << "NONE" << endl;
81 #endif
82 }
83 else
84 {
85 cout << devices.size() << endl;
86 for (unsigned int iDevicePtr = 0; iDevicePtr < devices.size(); iDevicePtr++)
87 {
88 CStdString strDevice;
89 strDevice.Format("device: %d\npath: %s\ncom port: %s", iDevicePtr, devices[iDevicePtr].path.c_str(), devices[0].comm.c_str());
90 cout << endl << strDevice.c_str() << endl;
91 }
92 }
93 }
94
95 void show_help(const char* strExec)
96 {
97 cout << endl <<
98 strExec << " {-h|--help|-l|--list-devices|[COM PORT]}" << endl <<
99 endl <<
100 "parameters:" << endl <<
101 "\t-h --help Shows this help text" << endl <<
102 "\t-l --list-devices List all devices on this system" << endl <<
103 "\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 <<
104 endl <<
105 "Type 'h' or 'help' and press enter after starting the client to display all available commands" << endl;
106 }
107
108 void show_console_help(void)
109 {
110 cout << endl <<
111 "================================================================================" << endl <<
112 "Available commands:" << endl <<
113 endl <<
114 "tx {bytes} transfer bytes over the CEC line." << endl <<
115 "[tx 40 00 FF 11 22 33] sends bytes 0x40 0x00 0xFF 0x11 0x22 0x33" << endl <<
116 endl <<
117 "am {ackmack} change the ackmask of the CEC adapter." << endl <<
118 "[am 10] ackmask 0x10 (logical address 4)" << endl <<
119 endl <<
120 "la {logical_address} change the logical address of the CEC adapter." << endl <<
121 "[la 4] logical address 4" << endl <<
122 endl <<
123 "[ping] send a ping command to the CEC adapter." << endl <<
124 "[bl] to let the adapter enter the bootloader, to upgrade the flash rom." << endl <<
125 "[h] or [help] show this help." << endl <<
126 "[q] or [quit] to quit the CEC test client and switch off all connected CEC devices." << endl <<
127 "================================================================================" << endl;
128 }
129
130 int main (int argc, char *argv[])
131 {
132 ICECDevice *parser = LoadLibCec("CEC Tester");
133 if (!parser && parser->GetMinVersion() > CEC_TEST_CLIENT_VERSION)
134 {
135 cout << "Unable to create parser. Is libcec.dll present?" << endl;
136 return 1;
137 }
138 CStdString strLog;
139 strLog.Format("CEC Parser created - libcec version %d", parser->GetLibVersion());
140 cout << strLog.c_str() << endl;
141
142 //make stdin non-blocking
143 #ifndef __WINDOWS__
144 int flags = fcntl(0, F_GETFL, 0);
145 flags |= O_NONBLOCK;
146 fcntl(0, F_SETFL, flags);
147 #endif
148
149 string strPort;
150 if (argc < 2)
151 {
152 cout << "no serial port given. trying autodetect: ";
153 vector<cec_device> devices;
154 int iDevicesFound = parser->FindDevices(devices);
155 if (iDevicesFound <= 0)
156 {
157 cout << "FAILED" << endl;
158 UnloadLibCec(parser);
159 return 1;
160 }
161 else
162 {
163 cout << endl << " path: " << devices[0].path << endl <<
164 " com port: " << devices[0].comm << endl << endl;
165 strPort = devices[0].comm;
166 }
167 }
168 else if (!strcmp(argv[1], "--list-devices") || !strcmp(argv[1], "-l"))
169 {
170 list_devices(parser);
171 UnloadLibCec(parser);
172 return 0;
173 }
174 else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
175 {
176 show_help(argv[0]);
177 return 0;
178 }
179 else
180 {
181 strPort = argv[1];
182 }
183
184 if (!parser->Open(strPort.c_str()))
185 {
186 cout << "unable to open the device on port " << strPort << endl;
187 flush_log(parser);
188 UnloadLibCec(parser);
189 return 1;
190 }
191
192 cout << "cec device opened" << endl;
193 usleep(CEC_SETTLE_DOWN_TIME);
194
195 parser->PowerOnDevices();
196 flush_log(parser);
197
198 parser->SetActiveView();
199 flush_log(parser);
200
201 bool bContinue(true);
202 cout << "waiting for input" << endl;
203 while (bContinue)
204 {
205 flush_log(parser);
206
207 string input;
208 getline(cin, input);
209 cin.clear();
210
211 if (!input.empty())
212 {
213 string command;
214 if (GetWord(input, command))
215 {
216 if (command == "tx")
217 {
218 string strvalue;
219 int ivalue;
220 vector<uint8_t> bytes;
221 while (GetWord(input, strvalue) && HexStrToInt(strvalue, ivalue))
222 bytes.push_back(ivalue);
223
224 parser->Transmit(bytes);
225 }
226 else if (command == "am")
227 {
228 string strvalue;
229 int ackmask;
230 if (GetWord(input, strvalue) && HexStrToInt(strvalue, ackmask))
231 {
232 parser->SetAckMask(ackmask);
233 }
234 }
235 else if (command == "la")
236 {
237 string strvalue;
238 if (GetWord(input, strvalue))
239 {
240 parser->SetLogicalAddress((cec_logical_address) atoi(strvalue.c_str()));
241 }
242 }
243 else if (command == "ping")
244 {
245 parser->Ping();
246 }
247 else if (command == "bl")
248 {
249 parser->StartBootloader();
250 }
251 else if (command == "h" || command == "help")
252 {
253 show_console_help();
254 }
255 else if (command == "q" || command == "quit")
256 {
257 bContinue = false;
258 }
259 }
260 if (bContinue)
261 cout << "waiting for input" << endl;
262 }
263 CCondition::Sleep(50);
264 }
265
266 parser->PowerOffDevices();
267 flush_log(parser);
268 UnloadLibCec(parser);
269 return 0;
270 }