+ return parser;
+}
+
+void ShowHelpConsole(void)
+{
+ cout << endl <<
+ "================================================================================" << endl <<
+ "Available commands:" << endl <<
+ endl <<
+ "tx {bytes} transfer bytes over the CEC line." << endl <<
+ "txn {bytes} transfer bytes but don't wait for transmission ACK." << endl <<
+ "[tx 40 00 FF 11 22 33] sends bytes 0x40 0x00 0xFF 0x11 0x22 0x33" << endl <<
+ endl <<
+ "on {address} power on the device with the given logical address." << endl <<
+ "[on 5] power on a connected audio system" << endl <<
+ endl <<
+ "standby {address} put the device with the given address in standby mode." << endl <<
+ "[standby 0] powers off the TV" << endl <<
+ endl <<
+ "la {logical_address} change the logical address of the CEC adapter." << endl <<
+ "[la 4] logical address 4" << endl <<
+ endl <<
+ "pa {physical_address} change the physical address of the CEC adapter." << endl <<
+ "[pa 10 00] physical address 1.0.0.0" << endl <<
+ endl <<
+ "osd {addr} {string} set OSD message on the specified device." << endl <<
+ "[osd 0 Test Message] displays 'Test Message' on the TV" << endl <<
+ endl <<
+ "ver {addr} get the CEC version of the specified device." << endl <<
+ "[ver 0] get the CEC version of the TV" << endl <<
+ endl <<
+ "ven {addr} get the vendor ID of the specified device." << endl <<
+ "[ven 0] get the vendor ID of the TV" << endl <<
+ endl <<
+ "lang {addr} get the menu language of the specified device." << endl <<
+ "[lang 0] get the menu language of the TV" << endl <<
+ endl <<
+ "pow {addr} get the power status of the specified device." << endl <<
+ "[pow 0] get the power status of the TV" << endl <<
+ endl <<
+ "poll {addr} poll the specified device." << endl <<
+ "[poll 0] sends a poll message to the TV" << endl <<
+ endl <<
+ "[mon] {1|0} enable or disable CEC bus monitoring." << endl <<
+ "[log] {1 - 31} change the log level. see cectypes.h for values." << endl <<
+ "[ping] send a ping command to the CEC adapter." << endl <<
+ "[bl] to let the adapter enter the bootloader, to upgrade" << endl <<
+ " the flash rom." << endl <<
+ "[r] reconnect to the CEC adapter." << endl <<
+ "[h] or [help] show this help." << endl <<
+ "[q] or [quit] to quit the CEC test client and switch off all" << endl <<
+ " connected CEC devices." << endl <<
+ "================================================================================" << endl;
+}
+
+int main (int argc, char *argv[])
+{
+ int iPhysicalAddress = -1;
+ cec_device_type_list typeList;
+ typeList.Clear();
+
+ int iArgPtr = 1;
+ bool bSingleCommand(false);
+ while (iArgPtr < argc)
+ {
+ if (argc >= iArgPtr + 1)
+ {
+ if (!strcmp(argv[iArgPtr], "-f") ||
+ !strcmp(argv[iArgPtr], "--log-file") ||
+ !strcmp(argv[iArgPtr], "-sf") ||
+ !strcmp(argv[iArgPtr], "--short-log-file"))
+ {
+ if (argc >= iArgPtr + 2)
+ {
+ g_logOutput.open(argv[iArgPtr + 1]);
+ g_bShortLog = (!strcmp(argv[iArgPtr], "-sf") || !strcmp(argv[iArgPtr], "--short-log-file"));
+ iArgPtr += 2;
+ }
+ else
+ {
+ cout << "== skipped log-file parameter: no file given ==" << endl;
+ ++iArgPtr;
+ }
+ }
+ else if (!strcmp(argv[iArgPtr], "-d") ||
+ !strcmp(argv[iArgPtr], "--log-level"))
+ {
+ if (argc >= iArgPtr + 2)
+ {
+ int iNewLevel = atoi(argv[iArgPtr + 1]);
+ if (iNewLevel >= CEC_LOG_ERROR && iNewLevel <= CEC_LOG_ALL)
+ {
+ g_cecLogLevel = iNewLevel;
+ if (!bSingleCommand)
+ cout << "log level set to " << argv[iArgPtr + 1] << endl;
+ }
+ else
+ {
+ cout << "== skipped log-level parameter: invalid level '" << argv[iArgPtr + 1] << "' ==" << endl;
+ }
+ iArgPtr += 2;
+ }
+ else
+ {
+ cout << "== skipped log-level parameter: no level given ==" << endl;
+ ++iArgPtr;
+ }
+ }
+ else if (!strcmp(argv[iArgPtr], "-t") ||
+ !strcmp(argv[iArgPtr], "--type"))
+ {
+ if (argc >= iArgPtr + 2)
+ {
+ if (!strcmp(argv[iArgPtr + 1], "p"))
+ {
+ if (!bSingleCommand)
+ cout << "== using device type 'playback device'" << endl;
+ typeList.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
+ }
+ else if (!strcmp(argv[iArgPtr + 1], "r"))
+ {
+ if (!bSingleCommand)
+ cout << "== using device type 'recording device'" << endl;
+ typeList.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+ }
+ else if (!strcmp(argv[iArgPtr + 1], "t"))
+ {
+ if (!bSingleCommand)
+ cout << "== using device type 'tuner'" << endl;
+ typeList.Add(CEC_DEVICE_TYPE_TUNER);
+ }
+ else if (!strcmp(argv[iArgPtr + 1], "a"))
+ {
+ if (!bSingleCommand)
+ cout << "== using device type 'audio system'" << endl;
+ typeList.Add(CEC_DEVICE_TYPE_AUDIO_SYSTEM);
+ }
+ else
+ {
+ cout << "== skipped invalid device type '" << argv[iArgPtr + 1] << "'" << endl;
+ }
+ ++iArgPtr;
+ }
+ ++iArgPtr;
+ }
+ else if (!strcmp(argv[iArgPtr], "--list-devices") ||
+ !strcmp(argv[iArgPtr], "-l"))
+ {
+ ICECAdapter *parser = CreateParser(typeList);
+ if (parser)
+ {
+ ListDevices(parser);
+ UnloadLibCec(parser);
+ }
+ return 0;
+ }
+ else if (!strcmp(argv[iArgPtr], "--single-command") ||
+ !strcmp(argv[iArgPtr], "-s"))
+ {
+ bSingleCommand = true;
+ ++iArgPtr;
+ }
+ else if (!strcmp(argv[iArgPtr], "--help") ||
+ !strcmp(argv[iArgPtr], "-h"))
+ {
+ ShowHelpCommandLine(argv[0]);
+ return 0;
+ }
+ else if (!strcmp(argv[iArgPtr], "-p") ||
+ !strcmp(argv[iArgPtr], "--physical"))
+ {
+ if (argc >= iArgPtr + 2)
+ {
+ if (sscanf(argv[iArgPtr + 1], "%x", &iPhysicalAddress))
+ cout << "using physical address '" << std::hex << iPhysicalAddress << "'" << endl;
+ else
+ cout << "== skipped physical address parameter: invalid physical address '" << argv[iArgPtr + 1] << "' ==" << endl;
+ ++iArgPtr;
+ }
+ ++iArgPtr;
+ }
+ else
+ {
+ g_strPort = argv[iArgPtr++];
+ }
+ }
+ }
+
+ if (typeList.IsEmpty())
+ {
+ if (!bSingleCommand)
+ cout << "No device type given. Using 'playback device'" << endl;
+ typeList.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
+ }
+
+ ICECAdapter *parser = LibCecInit("CECTester", typeList);
+ if (!parser || parser->GetMinLibVersion() > CEC_TEST_CLIENT_VERSION)
+ {
+#ifdef __WINDOWS__
+ cout << "Cannot load libcec.dll" << endl;
+#else
+ cout << "Cannot load libcec.so" << endl;