Server/CecSharpClient.cs
author Stephane Lenclud
Fri, 25 Sep 2015 12:28:47 +0200
changeset 161 7b19bea5d73a
permissions -rw-r--r--
CEC TV power on and standby working.
     1 /*
     2  * This file is part of the libCEC(R) library.
     3  *
     4  * libCEC(R) is Copyright (C) 2011-2013 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 using System;
    34 using System.Text;
    35 using CecSharp;
    36 
    37 namespace Cec
    38 {
    39     class Client : CecCallbackMethods
    40     {
    41         public Client()
    42         {
    43             Config = new LibCECConfiguration();
    44             Config.DeviceTypes.Types[0] = CecDeviceType.Tv;
    45             Config.DeviceName = "CEC";
    46             Config.HDMIPort = 2;
    47             //Config.ClientVersion = LibCECConfiguration.CurrentVersion;
    48             Config.SetCallbacks(this);
    49             LogLevel = (int)CecLogLevel.All;
    50 
    51             Lib = new LibCecSharp(Config);
    52             Lib.InitVideoStandalone();
    53 
    54             //Console.WriteLine("CEC Parser created - libCEC version " + Lib.VersionToString(Config.ServerVersion));
    55             Console.WriteLine("CEC Parser created - libCEC version " + Config.ServerVersion);
    56         }
    57 
    58         public override int ReceiveCommand(CecCommand command)
    59         {
    60             return 1;
    61         }
    62 
    63         public override int ReceiveKeypress(CecKeypress key)
    64         {
    65             return 1;
    66         }
    67 
    68         public override int ReceiveLogMessage(CecLogMessage message)
    69         {
    70             if (((int)message.Level & LogLevel) == (int)message.Level)
    71             {
    72                 string strLevel = "";
    73                 switch (message.Level)
    74                 {
    75                     case CecLogLevel.Error:
    76                         strLevel = "ERROR:     ";
    77                         break;
    78                     case CecLogLevel.Warning:
    79                         strLevel = "WARNING: ";
    80                         break;
    81                     case CecLogLevel.Notice:
    82                         strLevel = "NOTICE:    ";
    83                         break;
    84                     case CecLogLevel.Traffic:
    85                         strLevel = "TRAFFIC: ";
    86                         break;
    87                     case CecLogLevel.Debug:
    88                         strLevel = "DEBUG:     ";
    89                         break;
    90                     default:
    91                         break;
    92                 }
    93                 string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message);
    94                 Console.WriteLine(strLog);
    95             }
    96             return 1;
    97         }
    98 
    99         /// <summary>
   100         /// 
   101         /// </summary>
   102         /// <param name="timeout"></param>
   103         /// <returns></returns>
   104         public bool Connect(int timeout)
   105         {
   106             CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
   107             if (adapters.Length > 0)
   108                 return Connect(adapters[0].ComPort, timeout);
   109             else
   110             {
   111                 Console.WriteLine("Did not find any CEC adapters");
   112                 return false;
   113             }
   114         }
   115 
   116         public bool Connect(string port, int timeout)
   117         {
   118             return Lib.Open(port, timeout);
   119         }
   120 
   121         public void Close()
   122         {
   123             Lib.Close();
   124         }
   125 
   126         public void ListDevices()
   127         {
   128             int iAdapter = 0;
   129             foreach (CecAdapter adapter in Lib.FindAdapters(string.Empty))
   130             {
   131                 Console.WriteLine("Adapter:    " + iAdapter++);
   132                 Console.WriteLine("Path:         " + adapter.Path);
   133                 Console.WriteLine("Com port: " + adapter.ComPort);
   134             }
   135         }
   136 
   137         void ShowConsoleHelp()
   138         {
   139             Console.WriteLine(
   140                 "================================================================================" + Environment.NewLine +
   141                 "Available commands:" + Environment.NewLine +
   142                 Environment.NewLine +
   143                 "[tx] {bytes}                            transfer bytes over the CEC line." + Environment.NewLine +
   144                 "[txn] {bytes}                         transfer bytes but don't wait for transmission ACK." + Environment.NewLine +
   145                 "[on] {address}                        power on the device with the given logical address." + Environment.NewLine +
   146                 "[standby] {address}             put the device with the given address in standby mode." + Environment.NewLine +
   147                 "[la] {logical_address}        change the logical address of the CEC adapter." + Environment.NewLine +
   148                 "[pa] {physical_address}     change the physical address of the CEC adapter." + Environment.NewLine +
   149                 "[osd] {addr} {string}         set OSD message on the specified device." + Environment.NewLine +
   150                 "[ver] {addr}                            get the CEC version of the specified device." + Environment.NewLine +
   151                 "[ven] {addr}                            get the vendor ID of the specified device." + Environment.NewLine +
   152                 "[lang] {addr}                         get the menu language of the specified device." + Environment.NewLine +
   153                 "[pow] {addr}                            get the power status of the specified device." + Environment.NewLine +
   154                 "[poll] {addr}                         poll the specified device." + Environment.NewLine +
   155                 "[scan]                                        scan the CEC bus and display device info" + Environment.NewLine +
   156                 "[mon] {1|0}                             enable or disable CEC bus monitoring." + Environment.NewLine +
   157                 "[log] {1 - 31}                        change the log level. see cectypes.h for values." + Environment.NewLine +
   158                 "[ping]                                        send a ping command to the CEC adapter." + Environment.NewLine +
   159                 "[bl]                                            to let the adapter enter the bootloader, to upgrade" + Environment.NewLine +
   160                 "                                                    the flash rom." + Environment.NewLine +
   161                 "[r]                                             reconnect to the CEC adapter." + Environment.NewLine +
   162                 "[h] or [help]                         show this help." + Environment.NewLine +
   163                 "[q] or [quit]                         to quit the CEC test client and switch off all" + Environment.NewLine +
   164                 "                                                    connected CEC devices." + Environment.NewLine +
   165                 "================================================================================");
   166         }
   167 
   168         public void MainLoop()
   169         {
   170             bool bContinue = true;
   171             string command;
   172             while (bContinue)
   173             {
   174                 Console.WriteLine("waiting for input");
   175 
   176                 command = Console.ReadLine();
   177                 if (command != null && command.Length == 0)
   178                     continue;
   179                 string[] splitCommand = command.Split(' ');
   180                 if (splitCommand[0] == "tx" || splitCommand[0] == "txn")
   181                 {
   182                     CecCommand bytes = new CecCommand();
   183                     for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   184                     {
   185                         bytes.PushBack(byte.Parse(splitCommand[iPtr], System.Globalization.NumberStyles.HexNumber));
   186                     }
   187 
   188                     if (command == "txn")
   189                         bytes.TransmitTimeout = 0;
   190 
   191                     Lib.Transmit(bytes);
   192                 }
   193                 else if (splitCommand[0] == "on")
   194                 {
   195                     if (splitCommand.Length > 1)
   196                         Lib.PowerOnDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   197                     else
   198                         Lib.PowerOnDevices(CecLogicalAddress.Broadcast);
   199                 }
   200                 else if (splitCommand[0] == "standby")
   201                 {
   202                     if (splitCommand.Length > 1)
   203                         Lib.StandbyDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   204                     else
   205                         Lib.StandbyDevices(CecLogicalAddress.Broadcast);
   206                 }
   207                 else if (splitCommand[0] == "poll")
   208                 {
   209                     bool bSent = false;
   210                     if (splitCommand.Length > 1)
   211                         bSent = Lib.PollDevice((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   212                     else
   213                         bSent = Lib.PollDevice(CecLogicalAddress.Broadcast);
   214                     if (bSent)
   215                         Console.WriteLine("POLL message sent");
   216                     else
   217                         Console.WriteLine("POLL message not sent");
   218                 }
   219                 else if (splitCommand[0] == "la")
   220                 {
   221                     if (splitCommand.Length > 1)
   222                         Lib.SetLogicalAddress((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   223                 }
   224                 else if (splitCommand[0] == "pa")
   225                 {
   226                     if (splitCommand.Length > 1)
   227                         Lib.SetPhysicalAddress(ushort.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   228                 }
   229                 else if (splitCommand[0] == "osd")
   230                 {
   231                     if (splitCommand.Length > 2)
   232                     {
   233                         StringBuilder osdString = new StringBuilder();
   234                         for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   235                         {
   236                             osdString.Append(splitCommand[iPtr]);
   237                             if (iPtr != splitCommand.Length - 1)
   238                                 osdString.Append(" ");
   239                         }
   240                         Lib.SetOSDString((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber), CecDisplayControl.DisplayForDefaultTime, osdString.ToString());
   241                     }
   242                 }
   243                 else if (splitCommand[0] == "ping")
   244                 {
   245                     Lib.PingAdapter();
   246                 }
   247                 else if (splitCommand[0] == "mon")
   248                 {
   249                     bool enable = splitCommand.Length > 1 ? splitCommand[1] == "1" : false;
   250                     Lib.SwitchMonitoring(enable);
   251                 }
   252                 else if (splitCommand[0] == "bl")
   253                 {
   254                     Lib.StartBootloader();
   255                 }
   256                 else if (splitCommand[0] == "lang")
   257                 {
   258                     if (splitCommand.Length > 1)
   259                     {
   260                         string language = Lib.GetDeviceMenuLanguage((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   261                         Console.WriteLine("Menu language: " + language);
   262                     }
   263                 }
   264                 else if (splitCommand[0] == "ven")
   265                 {
   266                     if (splitCommand.Length > 1)
   267                     {
   268                         CecVendorId vendor = Lib.GetDeviceVendorId((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   269                         Console.WriteLine("Vendor ID: " + Lib.ToString(vendor));
   270                     }
   271                 }
   272                 else if (splitCommand[0] == "ver")
   273                 {
   274                     if (splitCommand.Length > 1)
   275                     {
   276                         CecVersion version = Lib.GetDeviceCecVersion((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   277                         Console.WriteLine("CEC version: " + Lib.ToString(version));
   278                     }
   279                 }
   280                 else if (splitCommand[0] == "pow")
   281                 {
   282                     if (splitCommand.Length > 1)
   283                     {
   284                         CecPowerStatus power = Lib.GetDevicePowerStatus((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   285                         Console.WriteLine("power status: " + Lib.ToString(power));
   286                     }
   287                 }
   288                 else if (splitCommand[0] == "r")
   289                 {
   290                     Console.WriteLine("closing the connection");
   291                     Lib.Close();
   292 
   293                     Console.WriteLine("opening a new connection");
   294                     Connect(10000);
   295 
   296                     Console.WriteLine("setting active source");
   297                     Lib.SetActiveSource(CecDeviceType.PlaybackDevice);
   298                 }
   299                 else if (splitCommand[0] == "scan")
   300                 {
   301                     StringBuilder output = new StringBuilder();
   302                     output.AppendLine("CEC bus information");
   303                     output.AppendLine("===================");
   304                     CecLogicalAddresses addresses = Lib.GetActiveDevices();
   305                     for (int iPtr = 0; iPtr < addresses.Addresses.Length; iPtr++)
   306                     {
   307                         CecLogicalAddress address = (CecLogicalAddress)iPtr;
   308                         if (!addresses.IsSet(address))
   309                             continue;
   310 
   311                         CecVendorId iVendorId = Lib.GetDeviceVendorId(address);
   312                         bool bActive = Lib.IsActiveDevice(address);
   313                         ushort iPhysicalAddress = Lib.GetDevicePhysicalAddress(address);
   314                         string strAddr = "todo: fixme"; //Lib.PhysicalAddressToString(iPhysicalAddress);
   315                         CecVersion iCecVersion = Lib.GetDeviceCecVersion(address);
   316                         CecPowerStatus power = Lib.GetDevicePowerStatus(address);
   317                         string osdName = Lib.GetDeviceOSDName(address);
   318                         string lang = Lib.GetDeviceMenuLanguage(address);
   319 
   320                         output.AppendLine("device #" + iPtr + ": " + Lib.ToString(address));
   321                         output.AppendLine("address:             " + strAddr);
   322                         output.AppendLine("active source: " + (bActive ? "yes" : "no"));
   323                         output.AppendLine("vendor:                " + Lib.ToString(iVendorId));
   324                         output.AppendLine("osd string:        " + osdName);
   325                         output.AppendLine("CEC version:     " + Lib.ToString(iCecVersion));
   326                         output.AppendLine("power status:    " + Lib.ToString(power));
   327                         if (!string.IsNullOrEmpty(lang))
   328                             output.AppendLine("language:            " + lang);
   329                         output.AppendLine("");
   330                     }
   331                     Console.WriteLine(output.ToString());
   332                 }
   333                 else if (splitCommand[0] == "h" || splitCommand[0] == "help")
   334                     ShowConsoleHelp();
   335                 else if (splitCommand[0] == "q" || splitCommand[0] == "quit")
   336                     bContinue = false;
   337                 else if (splitCommand[0] == "log" && splitCommand.Length > 1)
   338                     LogLevel = int.Parse(splitCommand[1]);                
   339             }
   340         }
   341 
   342         static void Main(string[] args)
   343         {
   344             Client p = new Client();
   345             if (p.Connect(10000))
   346             {
   347                 p.MainLoop();
   348             }
   349             else
   350             {
   351                 Console.WriteLine("Could not open a connection to the CEC adapter");
   352             }
   353         }
   354 
   355         /// <summary>
   356         /// 
   357         /// </summary>
   358         public void PowerOnDevices(CecLogicalAddress aAddress)
   359         {
   360             Lib.PowerOnDevices(aAddress);
   361         }
   362 
   363         /// <summary>
   364         /// 
   365         /// </summary>
   366         public void StandbyDevices(CecLogicalAddress aAddress)
   367         {
   368             Lib.StandbyDevices(aAddress);
   369         }
   370 
   371 
   372         private int LogLevel;
   373         private LibCecSharp Lib;
   374         private LibCECConfiguration Config;
   375     }
   376 }