Adding option to reconnect CEC before TV power action.
2 * This file is part of the libCEC(R) library.
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
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.
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.
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.
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
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/
36 using System.Threading;
40 class Client : CecCallbackMethods
45 /// <param name="aDeviceName"></param>
46 /// <param name="aHdmiPort"></param>
47 public Client(string aDeviceName, byte aHdmiPort, CecDeviceType aDeviceType = CecDeviceType.PlaybackDevice, CecLogLevel aLogLevel = CecLogLevel.Warning)
49 Config = new LibCECConfiguration();
50 Config.DeviceTypes.Types[0] = aDeviceType;
51 Config.DeviceName = aDeviceName;
52 Config.HDMIPort = aHdmiPort;
53 //Config.ClientVersion = LibCECConfiguration.CurrentVersion;
54 Config.SetCallbacks(this);
55 LogLevel = (int)aLogLevel;
57 iLib = new LibCecSharp(Config);
58 iLib.InitVideoStandalone();
60 //Console.WriteLine("CEC Parser created - libCEC version " + Lib.VersionToString(Config.ServerVersion));
61 Console.WriteLine("CEC Parser created - libCEC version " + Config.ServerVersion);
68 /// <param name="alert"></param>
69 /// <param name="data"></param>
70 /// <returns></returns>
71 public override int ReceiveAlert(CecAlert alert, CecParameter data)
73 string log = "CEC alert: " + alert.ToString();
74 if (data != null && data.Type == CecParameterType.ParameterTypeString)
76 log += " " + data.Data;
79 Console.WriteLine(log);
90 /// <param name="newVal"></param>
91 /// <returns></returns>
92 public override int ReceiveMenuStateChange(CecMenuState newVal)
94 Console.WriteLine("CEC menu state changed to: " + iLib.ToString(newVal));
101 /// <param name="logicalAddress"></param>
102 /// <param name="activated"></param>
103 public override void SourceActivated(CecLogicalAddress logicalAddress, bool activated)
105 Console.WriteLine("CEC source activated: " + iLib.ToString(logicalAddress) + "/" + activated.ToString() );
109 public override int ReceiveCommand(CecCommand command)
111 Console.WriteLine(string.Format("CEC command Src:{0} Dst:{1} Ack: {2} Eom: {3} OpcodeSet: {4} Opcode: {5} Timeout: {6}",
112 iLib.ToString(command.Initiator),
113 iLib.ToString(command.Destination),
114 command.Ack.ToString(),
115 command.Eom.ToString(),
116 command.OpcodeSet.ToString(),
117 iLib.ToString(command.Opcode),
118 command.TransmitTimeout.ToString()
123 public override int ReceiveKeypress(CecKeypress key)
125 Console.WriteLine(string.Format("CEC keypress: {0} Duration:{1} Empty: {2}",
126 key.Keycode.ToString(), key.Duration.ToString(), key.Empty.ToString()));
130 public override int ReceiveLogMessage(CecLogMessage message)
132 if (((int)message.Level & LogLevel) == (int)message.Level)
134 string strLevel = "";
135 switch (message.Level)
137 case CecLogLevel.Error:
138 strLevel = "ERROR: ";
140 case CecLogLevel.Warning:
141 strLevel = "WARNING: ";
143 case CecLogLevel.Notice:
144 strLevel = "NOTICE: ";
146 case CecLogLevel.Traffic:
147 strLevel = "TRAFFIC: ";
149 case CecLogLevel.Debug:
150 strLevel = "DEBUG: ";
155 string strLog = string.Format("{0} {1} {2}", strLevel, message.Time, message.Message);
156 Console.WriteLine(strLog);
165 /// <param name="timeout"></param>
166 /// <returns></returns>
167 public bool Connect(int timeout)
170 CecAdapter[] adapters = iLib.FindAdapters(string.Empty);
171 if (adapters.Length > 0)
173 Connect(adapters[0].ComPort, timeout);
177 Console.WriteLine("CEC did not find any adapters");
183 public bool Connect(string port, int timeout)
186 iConnected = iLib.Open(port, timeout);
202 public void TestSendKey()
204 //SetupMenu: opens option menu
205 //RootMenu: opens Android home menu
209 //Philips TopMenu = 16
210 //Philips PopupMenu = 17
212 //bool res = iLib.SendKeypress(CecLogicalAddress.Tv, CecUserControlCode.DisplayInformation, true);
213 //Thread.Sleep(3000); //Wait few seconds for menu to open
214 //res = iLib.SendKeypress(CecLogicalAddress.Tv, CecUserControlCode.SetupMenu, true);
216 for (int i = 0; i < 256; i++)
219 //res = iLib.SendKeyRelease(CecLogicalAddress.Tv, true);
221 switch ((CecUserControlCode)i)
223 case CecUserControlCode.Power:
224 case CecUserControlCode.PowerOffFunction:
225 case CecUserControlCode.PowerOnFunction:
226 case CecUserControlCode.PowerToggleFunction:
227 case CecUserControlCode.ElectronicProgramGuide:
228 case CecUserControlCode.InputSelect:
229 case CecUserControlCode.RootMenu:
234 Console.WriteLine(i.ToString());
236 iLib.SendKeypress(CecLogicalAddress.Tv, (CecUserControlCode)i, true);
246 for (int i=0;i<7;i++)
249 //res = iLib.SendKeyRelease(CecLogicalAddress.Tv, true);
251 //res = iLib.SendKeypress(CecLogicalAddress.Tv, CecUserControlCode.Down, true);
255 //res = iLib.SendKeypress(CecLogicalAddress.Tv, CecUserControlCode.Select, true);
257 //res = iLib.SendKeypress(CecLogicalAddress.Tv, CecUserControlCode.Select, true);
258 //res = iLib.SendKeyRelease(CecLogicalAddress.Tv, true);
266 Console.WriteLine("CEC bus information");
267 Console.WriteLine("===================");
268 CecLogicalAddresses addresses = Lib.GetActiveDevices();
269 for (int iPtr = 0; iPtr < addresses.Addresses.Length; iPtr++)
271 CecLogicalAddress address = (CecLogicalAddress) iPtr;
272 if (!addresses.IsSet(address))
275 CecVendorId iVendorId = Lib.GetDeviceVendorId(address);
276 bool bActive = Lib.IsActiveDevice(address);
277 ushort iPhysicalAddress = Lib.GetDevicePhysicalAddress(address);
278 string strAddr = Lib.PhysicalAddressToString(iPhysicalAddress);
279 CecVersion iCecVersion = Lib.GetDeviceCecVersion(address);
280 CecPowerStatus power = Lib.GetDevicePowerStatus(address);
281 string osdName = Lib.GetDeviceOSDName(address);
282 string lang = Lib.GetDeviceMenuLanguage(address);
284 Console.WriteLine("device #" + iPtr + ": " + Lib.ToString(address));
285 Console.WriteLine("address: " + strAddr);
286 Console.WriteLine("active source: " + (bActive ? "yes" : "no"));
287 Console.WriteLine("vendor: " + Lib.ToString(iVendorId));
288 Console.WriteLine("osd string: " + osdName);
289 Console.WriteLine("CEC version: " + Lib.ToString(iCecVersion));
290 Console.WriteLine("power status: " + Lib.ToString(power));
291 if (!string.IsNullOrEmpty(lang))
292 Console.WriteLine("language: " + lang);
293 Console.WriteLine("");
297 public void ListAdapters()
300 foreach (CecAdapter adapter in iLib.FindAdapters(string.Empty))
302 Console.WriteLine("Adapter: " + iAdapter++);
303 Console.WriteLine("Path: " + adapter.Path);
304 Console.WriteLine("Com port: " + adapter.ComPort);
308 void ShowConsoleHelp()
311 "================================================================================" + Environment.NewLine +
312 "Available commands:" + Environment.NewLine +
313 Environment.NewLine +
314 "[tx] {bytes} transfer bytes over the CEC line." + Environment.NewLine +
315 "[txn] {bytes} transfer bytes but don't wait for transmission ACK." + Environment.NewLine +
316 "[on] {address} power on the device with the given logical address." + Environment.NewLine +
317 "[standby] {address} put the device with the given address in standby mode." + Environment.NewLine +
318 "[la] {logical_address} change the logical address of the CEC adapter." + Environment.NewLine +
319 "[pa] {physical_address} change the physical address of the CEC adapter." + Environment.NewLine +
320 "[osd] {addr} {string} set OSD message on the specified device." + Environment.NewLine +
321 "[ver] {addr} get the CEC version of the specified device." + Environment.NewLine +
322 "[ven] {addr} get the vendor ID of the specified device." + Environment.NewLine +
323 "[lang] {addr} get the menu language of the specified device." + Environment.NewLine +
324 "[pow] {addr} get the power status of the specified device." + Environment.NewLine +
325 "[poll] {addr} poll the specified device." + Environment.NewLine +
326 "[scan] scan the CEC bus and display device info" + Environment.NewLine +
327 "[mon] {1|0} enable or disable CEC bus monitoring." + Environment.NewLine +
328 "[log] {1 - 31} change the log level. see cectypes.h for values." + Environment.NewLine +
329 "[ping] send a ping command to the CEC adapter." + Environment.NewLine +
330 "[bl] to let the adapter enter the bootloader, to upgrade" + Environment.NewLine +
331 " the flash rom." + Environment.NewLine +
332 "[r] reconnect to the CEC adapter." + Environment.NewLine +
333 "[h] or [help] show this help." + Environment.NewLine +
334 "[q] or [quit] to quit the CEC test client and switch off all" + Environment.NewLine +
335 " connected CEC devices." + Environment.NewLine +
336 "================================================================================");
339 public void MainLoop()
341 bool bContinue = true;
345 Console.WriteLine("waiting for input");
347 command = Console.ReadLine();
348 if (command != null && command.Length == 0)
350 string[] splitCommand = command.Split(' ');
351 if (splitCommand[0] == "tx" || splitCommand[0] == "txn")
353 CecCommand bytes = new CecCommand();
354 for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
356 bytes.PushBack(byte.Parse(splitCommand[iPtr], System.Globalization.NumberStyles.HexNumber));
359 if (command == "txn")
360 bytes.TransmitTimeout = 0;
362 iLib.Transmit(bytes);
364 else if (splitCommand[0] == "on")
366 if (splitCommand.Length > 1)
367 iLib.PowerOnDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
369 iLib.PowerOnDevices(CecLogicalAddress.Broadcast);
371 else if (splitCommand[0] == "standby")
373 if (splitCommand.Length > 1)
374 iLib.StandbyDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
376 iLib.StandbyDevices(CecLogicalAddress.Broadcast);
378 else if (splitCommand[0] == "poll")
381 if (splitCommand.Length > 1)
382 bSent = iLib.PollDevice((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
384 bSent = iLib.PollDevice(CecLogicalAddress.Broadcast);
386 Console.WriteLine("POLL message sent");
388 Console.WriteLine("POLL message not sent");
390 else if (splitCommand[0] == "la")
392 if (splitCommand.Length > 1)
393 iLib.SetLogicalAddress((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
395 else if (splitCommand[0] == "pa")
397 if (splitCommand.Length > 1)
398 iLib.SetPhysicalAddress(ushort.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
400 else if (splitCommand[0] == "osd")
402 if (splitCommand.Length > 2)
404 StringBuilder osdString = new StringBuilder();
405 for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
407 osdString.Append(splitCommand[iPtr]);
408 if (iPtr != splitCommand.Length - 1)
409 osdString.Append(" ");
411 iLib.SetOSDString((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber), CecDisplayControl.DisplayForDefaultTime, osdString.ToString());
414 else if (splitCommand[0] == "ping")
418 else if (splitCommand[0] == "mon")
420 bool enable = splitCommand.Length > 1 ? splitCommand[1] == "1" : false;
421 iLib.SwitchMonitoring(enable);
423 else if (splitCommand[0] == "bl")
425 iLib.StartBootloader();
427 else if (splitCommand[0] == "lang")
429 if (splitCommand.Length > 1)
431 string language = iLib.GetDeviceMenuLanguage((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
432 Console.WriteLine("Menu language: " + language);
435 else if (splitCommand[0] == "ven")
437 if (splitCommand.Length > 1)
439 CecVendorId vendor = iLib.GetDeviceVendorId((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
440 Console.WriteLine("Vendor ID: " + iLib.ToString(vendor));
443 else if (splitCommand[0] == "ver")
445 if (splitCommand.Length > 1)
447 CecVersion version = iLib.GetDeviceCecVersion((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
448 Console.WriteLine("CEC version: " + iLib.ToString(version));
451 else if (splitCommand[0] == "pow")
453 if (splitCommand.Length > 1)
455 CecPowerStatus power = iLib.GetDevicePowerStatus((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
456 Console.WriteLine("power status: " + iLib.ToString(power));
459 else if (splitCommand[0] == "r")
461 Console.WriteLine("closing the connection");
464 Console.WriteLine("opening a new connection");
467 Console.WriteLine("setting active source");
468 iLib.SetActiveSource(CecDeviceType.PlaybackDevice);
470 else if (splitCommand[0] == "scan")
472 StringBuilder output = new StringBuilder();
473 output.AppendLine("CEC bus information");
474 output.AppendLine("===================");
475 CecLogicalAddresses addresses = iLib.GetActiveDevices();
476 for (int iPtr = 0; iPtr < addresses.Addresses.Length; iPtr++)
478 CecLogicalAddress address = (CecLogicalAddress)iPtr;
479 if (!addresses.IsSet(address))
482 CecVendorId iVendorId = iLib.GetDeviceVendorId(address);
483 bool bActive = iLib.IsActiveDevice(address);
484 ushort iPhysicalAddress = iLib.GetDevicePhysicalAddress(address);
485 string strAddr = "todo: fixme"; //Lib.PhysicalAddressToString(iPhysicalAddress);
486 CecVersion iCecVersion = iLib.GetDeviceCecVersion(address);
487 CecPowerStatus power = iLib.GetDevicePowerStatus(address);
488 string osdName = iLib.GetDeviceOSDName(address);
489 string lang = iLib.GetDeviceMenuLanguage(address);
491 output.AppendLine("device #" + iPtr + ": " + iLib.ToString(address));
492 output.AppendLine("address: " + strAddr);
493 output.AppendLine("active source: " + (bActive ? "yes" : "no"));
494 output.AppendLine("vendor: " + iLib.ToString(iVendorId));
495 output.AppendLine("osd string: " + osdName);
496 output.AppendLine("CEC version: " + iLib.ToString(iCecVersion));
497 output.AppendLine("power status: " + iLib.ToString(power));
498 if (!string.IsNullOrEmpty(lang))
499 output.AppendLine("language: " + lang);
500 output.AppendLine("");
502 Console.WriteLine(output.ToString());
504 else if (splitCommand[0] == "h" || splitCommand[0] == "help")
506 else if (splitCommand[0] == "q" || splitCommand[0] == "quit")
508 else if (splitCommand[0] == "log" && splitCommand.Length > 1)
509 LogLevel = int.Parse(splitCommand[1]);
514 /// Provide direct access to CEC library
516 public LibCecSharp Lib
527 private int LogLevel;
531 private LibCecSharp iLib;
535 private LibCECConfiguration Config;
540 private bool iConnected;