cec: added -f and --log-file parameters to cec-client
[deb_libcec.git] / src / testclient / main.cpp
index dc20968dd60952bc7f3e42366a58cb770c95669f..be3018c68646a66bfa58361984e1d3f1c0d342f9 100644 (file)
  *     http://www.pulse-eight.net/
  */
 
-#include <libcec/CECExports.h>
+#include <cec.h>
 
 #include <cstdio>
 #include <fcntl.h>
 #include <iostream>
+#include <fstream>
 #include <string>
 #include <sstream>
 #include "../lib/platform/threads.h"
 using namespace CEC;
 using namespace std;
 
-#define CEC_TEST_CLIENT_VERSION 7
+#define CEC_TEST_CLIENT_VERSION 8
 
-#include <libcec/CECLoader.h>
+#include <cecloader.h>
+int g_cecLogLevel = CEC_LOG_ALL;
+ofstream g_logOutput;
 
 inline bool HexStrToInt(const std::string& data, uint8_t& value)
 {
@@ -104,25 +107,37 @@ void flush_log(ICECAdapter *cecParser)
   cec_log_message message;
   while (cecParser && cecParser->GetNextLogMessage(&message))
   {
-    switch (message.level)
+    if ((message.level & g_cecLogLevel) == message.level)
     {
-    case CEC_LOG_ERROR:
-      cout << "ERROR:   ";
-      break;
-    case CEC_LOG_WARNING:
-      cout << "WARNING: ";
-      break;
-    case CEC_LOG_NOTICE:
-      cout << "NOTICE:  ";
-      break;
-    case CEC_LOG_DEBUG:
-      cout << "DEBUG:   ";
-      break;
-    }
+      CStdString strLevel;
+      switch (message.level)
+      {
+      case CEC_LOG_ERROR:
+        strLevel = "ERROR:   ";
+        break;
+      case CEC_LOG_WARNING:
+        strLevel = "WARNING: ";
+        break;
+      case CEC_LOG_NOTICE:
+        strLevel = "NOTICE:  ";
+        break;
+      case CEC_LOG_TRAFFIC:
+        strLevel = "TRAFFIC: ";
+        break;
+      case CEC_LOG_DEBUG:
+        strLevel = "DEBUG:   ";
+        break;
+      default:
+        break;
+      }
 
-    CStdString strMessageTmp;
-    strMessageTmp.Format("[%16lld]\t%s", message.time, message.message);
-    cout << strMessageTmp.c_str() << endl;
+      CStdString strMessageTmp;
+      strMessageTmp.Format("[%16lld]\t%s", message.time, message.message);
+      cout << strLevel.c_str() << strMessageTmp.c_str() << endl;
+
+      if (g_logOutput.is_open())
+        g_logOutput << strLevel.c_str() << strMessageTmp.c_str() << endl;
+    }
   }
 }
 
@@ -156,6 +171,7 @@ void show_help(const char* strExec)
       "parameters:" << endl <<
       "\t-h --help            Shows this help text" << endl <<
       "\t-l --list-devices    List all devices on this system" << endl <<
+      "\t-f --log-file {file} Writes all libCEC log message to a file" << endl <<
       "\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 <<
       endl <<
       "Type 'h' or 'help' and press enter after starting the client to display all available commands" << endl;
@@ -168,6 +184,7 @@ void show_console_help(void)
   "Available commands:" << endl <<
   endl <<
   "tx {bytes}                transfer bytes over the CEC line." << endl <<
+  "txn {bytes}               transfer bytes and don't wait for an ACK reply." << 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 <<
@@ -179,6 +196,14 @@ void show_console_help(void)
   "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 <<
+  "[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 <<
@@ -213,7 +238,22 @@ int main (int argc, char *argv[])
 #endif
 
   string strPort;
-  if (argc < 2)
+  int iArgPtr = 0;
+  if (argc >= 3)
+  {
+    if (!strcmp(argv[1], "-f"))
+    {
+      g_logOutput.open(argv[2]);
+      iArgPtr = 2;
+    }
+    else if (!strcmp(argv[1], "--file"))
+    {
+      g_logOutput.open(argv[2]);
+      iArgPtr = 2;
+    }
+  }
+
+  if (argc < 2 + iArgPtr)
   {
     cout << "no serial port given. trying autodetect: ";
     cec_adapter devices[10];
@@ -231,22 +271,23 @@ int main (int argc, char *argv[])
       strPort = devices[0].comm;
     }
   }
-  else if (!strcmp(argv[1], "--list-devices") || !strcmp(argv[1], "-l"))
+  else if (!strcmp(argv[1 + iArgPtr], "--list-devices") || !strcmp(argv[1 + iArgPtr], "-l"))
   {
     list_devices(parser);
     UnloadLibCec(parser);
     return 0;
   }
-  else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
+  else if (!strcmp(argv[1 + iArgPtr], "--help") || !strcmp(argv[1 + iArgPtr], "-h"))
   {
     show_help(argv[0]);
     return 0;
   }
   else
   {
-    strPort = argv[1];
+    strPort = argv[1 + iArgPtr];
   }
 
+
   if (!parser->Open(strPort.c_str()))
   {
     cout << "unable to open the device on port " << strPort << endl;
@@ -278,7 +319,7 @@ int main (int argc, char *argv[])
       string command;
       if (GetWord(input, command))
       {
-        if (command == "tx")
+        if (command == "tx" || command == "txn")
         {
           string strvalue;
           uint8_t ivalue;
@@ -286,9 +327,9 @@ int main (int argc, char *argv[])
           bytes.clear();
 
           while (GetWord(input, strvalue) && HexStrToInt(strvalue, ivalue))
-          bytes.push_back(ivalue);
+            bytes.push_back(ivalue);
 
-          parser->Transmit(bytes);
+          parser->Transmit(bytes, command == "tx");
         }
         else if (command == "on")
         {
@@ -324,10 +365,48 @@ int main (int argc, char *argv[])
             parser->SetLogicalAddress((cec_logical_address) atoi(strvalue.c_str()));
           }
         }
+        else if (command == "pa")
+        {
+          string strB1, strB2;
+          uint8_t iB1, iB2;
+          if (GetWord(input, strB1) && HexStrToInt(strB1, iB1) &&
+              GetWord(input, strB2) && HexStrToInt(strB2, iB2))
+          {
+            uint16_t iPhysicalAddress = ((uint16_t)iB1 << 8) + iB2;
+            parser->SetPhysicalAddress(iPhysicalAddress);
+          }
+        }
+        else if (command == "osd")
+        {
+          bool bFirstWord(false);
+          string strAddr, strMessage, strWord;
+          uint8_t iAddr;
+          if (GetWord(input, strAddr) && HexStrToInt(strAddr, iAddr) && iAddr < 0xF)
+          {
+            while (GetWord(input, strWord))
+            {
+              if (bFirstWord)
+              {
+                bFirstWord = false;
+                strMessage.append(" ");
+              }
+              strMessage.append(strWord);
+            }
+            parser->SetOSDString((cec_logical_address) iAddr, CEC_DISPLAY_CONTROL_DISPLAY_FOR_DEFAULT_TIME, strMessage.c_str());
+          }
+        }
         else if (command == "ping")
         {
           parser->PingAdapter();
         }
+        else if (command == "mon")
+        {
+          CStdString strEnable;
+          if (GetWord(input, strEnable) && (strEnable.Equals("0") || strEnable.Equals("1")))
+          {
+            parser->SwitchMonitoring(strEnable.Equals("1"));
+          }
+        }
         else if (command == "bl")
         {
           parser->StartBootloader();
@@ -353,6 +432,19 @@ int main (int argc, char *argv[])
         {
           bContinue = false;
         }
+        else if (command == "log")
+        {
+          CStdString strLevel;
+          if (GetWord(input, strLevel))
+          {
+            int iNewLevel = atoi(strLevel);
+            if (iNewLevel >= CEC_LOG_ERROR && iNewLevel <= CEC_LOG_ALL)
+            {
+              g_cecLogLevel = iNewLevel;
+              cout << "log level changed to " << strLevel.c_str() << endl;
+            }
+          }
+        }
       }
       if (bContinue)
         cout << "waiting for input" << endl;
@@ -364,5 +456,9 @@ int main (int argc, char *argv[])
   parser->Close();
   flush_log(parser);
   UnloadLibCec(parser);
+
+  if (g_logOutput.is_open())
+    g_logOutput.close();
+
   return 0;
 }