added missing hardy rules and source version
[deb_libcec.git] / src / lib / LibCEC.cpp
CommitLineData
2abe74eb
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
b492c10e 4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
2abe74eb
LOK
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 "LibCEC.h"
34
7bb4ed43 35#include "adapter/USBCECAdapterDetection.h"
08d80226 36#include "adapter/USBCECAdapterCommunication.h"
2abe74eb 37#include "CECProcessor.h"
004b8382 38#include "devices/CECAudioSystem.h"
0f23c85c 39#include "devices/CECBusDevice.h"
004b8382
LOK
40#include "devices/CECPlaybackDevice.h"
41#include "devices/CECTV.h"
ba65909d
LOK
42#include "platform/util/timeutils.h"
43#include "platform/util/StdString.h"
2abe74eb 44
004b8382
LOK
45#include "CECClient.h"
46
2abe74eb
LOK
47using namespace std;
48using namespace CEC;
f00ff009 49using namespace PLATFORM;
2abe74eb 50
c30acafa
LOK
51CLibCEC::CLibCEC(const char *UNUSED(strDeviceName), cec_device_type_list UNUSED(types), uint16_t UNUSED(iPhysicalAddress) /* = 0 */) :
52 m_iStartTime(GetTimeMs()),
53 m_client(NULL)
54{
55 m_cec = new CCECProcessor(this);
56}
57
58CLibCEC::CLibCEC(libcec_configuration *UNUSED(configuration)) :
59 m_iStartTime(GetTimeMs()),
60 m_client(NULL)
caca2d81 61{
004b8382 62 m_cec = new CCECProcessor(this);
f8513317
LOK
63}
64
2abe74eb
LOK
65CLibCEC::~CLibCEC(void)
66{
c0152c09
LOK
67 // unregister all clients client
68 UnregisterClients();
69
70 // delete the adapter connection
2abe74eb 71 delete m_cec;
004b8382 72 m_cec = NULL;
2abe74eb
LOK
73}
74
b32ffd87 75bool CLibCEC::Open(const char *strPort, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
2abe74eb 76{
c0152c09 77 if (!m_cec || !strPort)
99aeafb9
LOK
78 return false;
79
c0152c09 80 // open a new connection
b32ffd87 81 if (!m_cec->Start(strPort, CEC_SERIAL_DEFAULT_BAUDRATE, iTimeoutMs))
2abe74eb
LOK
82 {
83 AddLog(CEC_LOG_ERROR, "could not start CEC communications");
84 return false;
85 }
86
c0152c09 87 // register all clients
004b8382
LOK
88 for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
89 {
90 if (!m_cec->RegisterClient(*it))
91 {
92 AddLog(CEC_LOG_ERROR, "failed to register a CEC client");
93 return false;
94 }
95 }
96
2abe74eb
LOK
97 return true;
98}
99
100void CLibCEC::Close(void)
101{
c0152c09
LOK
102 // unregister all clients
103 UnregisterClients();
104
105 // close the connection
fa4798bd 106 if (m_cec)
99aeafb9 107 m_cec->Close();
fa4798bd
LOK
108}
109
25701fa6 110int8_t CLibCEC::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
2abe74eb 111{
7bb4ed43 112 return CUSBCECAdapterDetection::FindAdapters(deviceList, iBufSize, strDevicePath);
2abe74eb
LOK
113}
114
2abe74eb
LOK
115bool CLibCEC::StartBootloader(void)
116{
1113cb7d 117 return m_cec ? m_cec->StartBootloader() : false;
2abe74eb
LOK
118}
119
c0152c09 120bool CLibCEC::PingAdapter(void)
2abe74eb 121{
c0152c09 122 return m_client ? m_client->PingAdapter() : false;
2abe74eb
LOK
123}
124
c0152c09 125bool CLibCEC::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks)
a9232a79 126{
c0152c09 127 return m_client ? m_client->EnableCallbacks(cbParam, callbacks) : false;
a9232a79
LOK
128}
129
c0152c09 130bool CLibCEC::GetCurrentConfiguration(libcec_configuration *configuration)
2abe74eb 131{
c0152c09 132 return m_client ? m_client->GetCurrentConfiguration(*configuration) : false;
2abe74eb
LOK
133}
134
c0152c09 135bool CLibCEC::SetConfiguration(const libcec_configuration *configuration)
28fa6c97 136{
c0152c09 137 return m_client ? m_client->SetConfiguration(*configuration) : false;
28fa6c97
LOK
138}
139
004b8382 140bool CLibCEC::CanPersistConfiguration(void)
1969b140 141{
c0152c09 142 return m_client ? m_client->CanPersistConfiguration() : false;
1969b140
LOK
143}
144
004b8382 145bool CLibCEC::PersistConfiguration(libcec_configuration *configuration)
8b7e5ff6 146{
c0152c09 147 return m_client ? m_client->PersistConfiguration(*configuration) : false;
8b7e5ff6
LOK
148}
149
004b8382 150void CLibCEC::RescanActiveDevices(void)
6a1c0009 151{
c0152c09
LOK
152 if (m_client)
153 m_client->RescanActiveDevices();
44c74256
LOK
154}
155
c0152c09 156bool CLibCEC::IsLibCECActiveSource(void)
eab72c40 157{
c0152c09 158 return m_client ? m_client->IsLibCECActiveSource() : false;
eab72c40
LOK
159}
160
004b8382 161bool CLibCEC::Transmit(const cec_command &data)
b4b1b49b 162{
004b8382 163 return m_client ? m_client->Transmit(data) : false;
b4b1b49b
LOK
164}
165
004b8382 166bool CLibCEC::SetLogicalAddress(cec_logical_address iLogicalAddress)
b4b1b49b 167{
004b8382 168 return m_client ? m_client->SetLogicalAddress(iLogicalAddress) : false;
b4b1b49b
LOK
169}
170
004b8382 171bool CLibCEC::SetPhysicalAddress(uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */)
e55f3f70 172{
004b8382 173 return m_client ? m_client->SetPhysicalAddress(iPhysicalAddress) : false;
e55f3f70 174}
44c74256 175
004b8382 176bool CLibCEC::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
57f45e6c 177{
004b8382 178 return m_client ? m_client->SetHDMIPort(iBaseDevice, iPort) : false;
57f45e6c
LOK
179}
180
004b8382 181bool CLibCEC::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */)
6d858ba4 182{
004b8382 183 return m_client ? m_client->SendPowerOnDevices(address) : false;
6d858ba4
LOK
184}
185
004b8382 186bool CLibCEC::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */)
6d858ba4 187{
004b8382 188 return m_client ? m_client->SendStandbyDevices(address) : false;
6d858ba4
LOK
189}
190
004b8382 191bool CLibCEC::SetActiveSource(cec_device_type type /* = CEC_DEVICE_TYPE_RESERVED */)
6d858ba4 192{
004b8382 193 return m_client ? m_client->SendSetActiveSource(type) : false;
6d858ba4
LOK
194}
195
004b8382 196bool CLibCEC::SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate /* = true */)
04e637f9 197{
004b8382 198 return m_client ? m_client->SendSetDeckControlMode(mode, bSendUpdate) : false;
04e637f9
LOK
199}
200
004b8382 201bool CLibCEC::SetDeckInfo(cec_deck_info info, bool bSendUpdate /* = true */)
04e637f9 202{
004b8382 203 return m_client ? m_client->SendSetDeckInfo(info, bSendUpdate) : false;
04e637f9
LOK
204}
205
004b8382 206bool CLibCEC::SetInactiveView(void)
04e637f9 207{
004b8382 208 return m_client ? m_client->SendSetInactiveView() : false;
04e637f9
LOK
209}
210
004b8382 211bool CLibCEC::SetMenuState(cec_menu_state state, bool bSendUpdate /* = true */)
a33794d8 212{
004b8382 213 return m_client ? m_client->SendSetMenuState(state, bSendUpdate) : false;
a33794d8
LOK
214}
215
004b8382 216bool CLibCEC::SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage)
a33794d8 217{
004b8382 218 return m_client ? m_client->SendSetOSDString(iLogicalAddress, duration, strMessage) : false;
a33794d8
LOK
219}
220
c0152c09
LOK
221bool CLibCEC::SwitchMonitoring(bool bEnable)
222{
223 return m_client ? m_client->SwitchMonitoring(bEnable) : false;
224}
225
004b8382 226cec_version CLibCEC::GetDeviceCecVersion(cec_logical_address iAddress)
ed21be2a 227{
004b8382 228 return m_client ? m_client->GetDeviceCecVersion(iAddress) : CEC_VERSION_UNKNOWN;
ed21be2a
LOK
229}
230
004b8382 231bool CLibCEC::GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language)
2abe74eb 232{
c0152c09 233 return m_client ? m_client->GetDeviceMenuLanguage(iAddress, *language) : false;
2abe74eb
LOK
234}
235
004b8382 236uint64_t CLibCEC::GetDeviceVendorId(cec_logical_address iAddress)
95ba7a09 237{
004b8382 238 return m_client ? m_client->GetDeviceVendorId(iAddress) : (uint64_t)CEC_VENDOR_UNKNOWN;
02e7043e
LOK
239}
240
004b8382 241uint16_t CLibCEC::GetDevicePhysicalAddress(cec_logical_address iAddress)
32403cc3 242{
004b8382 243 return m_client ? m_client->GetDevicePhysicalAddress(iAddress) : CEC_INVALID_PHYSICAL_ADDRESS;
32403cc3
LOK
244}
245
004b8382 246cec_power_status CLibCEC::GetDevicePowerStatus(cec_logical_address iAddress)
02e7043e 247{
004b8382 248 return m_client ? m_client->GetDevicePowerStatus(iAddress) : CEC_POWER_STATUS_UNKNOWN;
95ba7a09
LOK
249}
250
c0152c09
LOK
251bool CLibCEC::PollDevice(cec_logical_address iAddress)
252{
253 return m_client ? m_client->PollDevice(iAddress) : false;
254}
255
256cec_logical_addresses CLibCEC::GetActiveDevices(void)
257{
258 cec_logical_addresses addresses;
259 addresses.Clear();
260 if (m_client)
261 addresses = m_client->GetActiveDevices();
262 return addresses;
263}
264
265bool CLibCEC::IsActiveDevice(cec_logical_address iAddress)
266{
267 return m_client ? m_client->IsActiveDevice(iAddress) : false;
268}
269
270bool CLibCEC::IsActiveDeviceType(cec_device_type type)
271{
272 return m_client ? m_client->IsActiveDeviceType(type) : false;
273}
274
004b8382 275uint8_t CLibCEC::VolumeUp(bool bSendRelease /* = true */)
2abe74eb 276{
004b8382 277 return m_client ? m_client->SendVolumeUp(bSendRelease) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
2abe74eb
LOK
278}
279
004b8382 280uint8_t CLibCEC::VolumeDown(bool bSendRelease /* = true */)
2abe74eb 281{
004b8382 282 return m_client ? m_client->SendVolumeDown(bSendRelease) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
2abe74eb
LOK
283}
284
004b8382 285uint8_t CLibCEC::MuteAudio(bool UNUSED(bSendRelease) /* = true */)
b1c47f9d 286{
004b8382 287 return m_client ? m_client->SendMuteAudio() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
b1c47f9d
LOK
288}
289
004b8382 290bool CLibCEC::SendKeypress(cec_logical_address iDestination, cec_user_control_code key, bool bWait /* = true */)
2abe74eb 291{
004b8382 292 return m_client ? m_client->SendKeypress(iDestination, key, bWait) : false;
2abe74eb
LOK
293}
294
004b8382 295bool CLibCEC::SendKeyRelease(cec_logical_address iDestination, bool bWait /* = true */)
e1804a4e 296{
004b8382 297 return m_client ? m_client->SendKeyRelease(iDestination, bWait) : false;
e1804a4e
LOK
298}
299
004b8382 300cec_osd_name CLibCEC::GetDeviceOSDName(cec_logical_address iAddress)
f42d3e0f 301{
004b8382 302 cec_osd_name retVal;
20505741
LOK
303 retVal.device = CECDEVICE_UNKNOWN;
304 memset(retVal.name, 0, 14);
305
004b8382
LOK
306 if (m_client)
307 retVal = m_client->GetDeviceOSDName(iAddress);
308 return retVal;
f42d3e0f
LOK
309}
310
c0152c09
LOK
311cec_logical_address CLibCEC::GetActiveSource(void)
312{
313 return m_client ? m_client->GetActiveSource() : CECDEVICE_UNKNOWN;
314}
315
316bool CLibCEC::IsActiveSource(cec_logical_address iAddress)
317{
318 return m_client ? m_client->IsActiveSource(iAddress) : false;
319}
320bool CLibCEC::SetStreamPath(cec_logical_address iAddress)
321{
322 return m_client ? m_client->SetStreamPath(iAddress) : false;
323}
324
325bool CLibCEC::SetStreamPath(uint16_t iPhysicalAddress)
326{
327 return m_client ? m_client->SetStreamPath(iPhysicalAddress) : false;
328}
329
004b8382 330cec_logical_addresses CLibCEC::GetLogicalAddresses(void)
f42d3e0f 331{
004b8382 332 cec_logical_addresses addresses;
c30acafa 333 addresses.Clear();
c0152c09
LOK
334 if (m_client)
335 m_client->GetLogicalAddresses();
004b8382 336 return addresses;
f42d3e0f
LOK
337}
338
004b8382 339bool CLibCEC::GetNextLogMessage(cec_log_message *message)
80b72250 340{
004b8382 341 return m_client ? m_client->GetNextLogMessage(message) : false;
80b72250
LOK
342}
343
004b8382 344bool CLibCEC::GetNextKeypress(cec_keypress *key)
5477a250 345{
004b8382 346 return m_client ? m_client->GetNextKeypress(key) : false;
5477a250
LOK
347}
348
004b8382 349bool CLibCEC::GetNextCommand(cec_command *command)
5477a250 350{
004b8382 351 return m_client ? m_client->GetNextCommand(command) : false;
5477a250
LOK
352}
353
004b8382 354cec_device_type CLibCEC::GetType(cec_logical_address address)
f8513317 355{
004b8382
LOK
356 switch (address)
357 {
358 case CECDEVICE_AUDIOSYSTEM:
359 return CEC_DEVICE_TYPE_AUDIO_SYSTEM;
360 case CECDEVICE_PLAYBACKDEVICE1:
361 case CECDEVICE_PLAYBACKDEVICE2:
362 case CECDEVICE_PLAYBACKDEVICE3:
363 return CEC_DEVICE_TYPE_PLAYBACK_DEVICE;
364 case CECDEVICE_RECORDINGDEVICE1:
365 case CECDEVICE_RECORDINGDEVICE2:
366 case CECDEVICE_RECORDINGDEVICE3:
367 return CEC_DEVICE_TYPE_RECORDING_DEVICE;
368 case CECDEVICE_TUNER1:
369 case CECDEVICE_TUNER2:
370 case CECDEVICE_TUNER3:
371 case CECDEVICE_TUNER4:
372 return CEC_DEVICE_TYPE_TUNER;
373 case CECDEVICE_TV:
374 return CEC_DEVICE_TYPE_TV;
375 default:
376 return CEC_DEVICE_TYPE_RESERVED;
377 }
f8513317
LOK
378}
379
004b8382 380uint16_t CLibCEC::GetMaskForType(cec_logical_address address)
caca2d81 381{
004b8382 382 return GetMaskForType(GetType(address));
caca2d81
LOK
383}
384
004b8382 385uint16_t CLibCEC::GetMaskForType(cec_device_type type)
a2198e5e 386{
004b8382 387 switch (type)
a2198e5e 388 {
004b8382 389 case CEC_DEVICE_TYPE_AUDIO_SYSTEM:
08d80226 390 {
004b8382
LOK
391 cec_logical_addresses addr;
392 addr.Clear();
393 addr.Set(CECDEVICE_AUDIOSYSTEM);
394 return addr.AckMask();
08d80226 395 }
004b8382
LOK
396 case CEC_DEVICE_TYPE_PLAYBACK_DEVICE:
397 {
398 cec_logical_addresses addr;
399 addr.Clear();
400 addr.Set(CECDEVICE_PLAYBACKDEVICE1);
401 addr.Set(CECDEVICE_PLAYBACKDEVICE2);
402 addr.Set(CECDEVICE_PLAYBACKDEVICE3);
403 return addr.AckMask();
404 }
405 case CEC_DEVICE_TYPE_RECORDING_DEVICE:
406 {
407 cec_logical_addresses addr;
408 addr.Clear();
409 addr.Set(CECDEVICE_RECORDINGDEVICE1);
410 addr.Set(CECDEVICE_RECORDINGDEVICE2);
411 addr.Set(CECDEVICE_RECORDINGDEVICE3);
412 return addr.AckMask();
413 }
414 case CEC_DEVICE_TYPE_TUNER:
415 {
416 cec_logical_addresses addr;
417 addr.Clear();
418 addr.Set(CECDEVICE_TUNER1);
419 addr.Set(CECDEVICE_TUNER2);
420 addr.Set(CECDEVICE_TUNER3);
421 addr.Set(CECDEVICE_TUNER4);
422 return addr.AckMask();
423 }
424 case CEC_DEVICE_TYPE_TV:
425 {
426 cec_logical_addresses addr;
427 addr.Clear();
428 addr.Set(CECDEVICE_TV);
429 return addr.AckMask();
430 }
431 default:
432 return 0;
a2198e5e 433 }
004b8382 434}
08d80226 435
004b8382
LOK
436bool CLibCEC::IsValidPhysicalAddress(uint16_t iPhysicalAddress)
437{
438 return iPhysicalAddress >= CEC_MIN_PHYSICAL_ADDRESS &&
439 iPhysicalAddress <= CEC_MAX_PHYSICAL_ADDRESS;
a2198e5e
LOK
440}
441
004b8382 442const char *CLibCEC::ToString(const cec_device_type type)
25701fa6 443{
004b8382
LOK
444 switch (type)
445 {
446 case CEC_DEVICE_TYPE_AUDIO_SYSTEM:
447 return "audio system";
448 case CEC_DEVICE_TYPE_PLAYBACK_DEVICE:
449 return "playback device";
450 case CEC_DEVICE_TYPE_RECORDING_DEVICE:
451 return "recording device";
452 case CEC_DEVICE_TYPE_RESERVED:
453 return "reserved";
454 case CEC_DEVICE_TYPE_TUNER:
455 return "tuner";
456 case CEC_DEVICE_TYPE_TV:
457 return "TV";
458 default:
459 return "unknown";
460 }
25701fa6 461}
03ae897d
LOK
462
463const char *CLibCEC::ToString(const cec_menu_state state)
464{
004b8382
LOK
465 switch (state)
466 {
467 case CEC_MENU_STATE_ACTIVATED:
468 return "activated";
469 case CEC_MENU_STATE_DEACTIVATED:
470 return "deactivated";
471 default:
472 return "unknown";
473 }
03ae897d
LOK
474}
475
476const char *CLibCEC::ToString(const cec_version version)
477{
004b8382
LOK
478 switch (version)
479 {
480 case CEC_VERSION_1_2:
481 return "1.2";
482 case CEC_VERSION_1_2A:
483 return "1.2a";
484 case CEC_VERSION_1_3:
485 return "1.3";
486 case CEC_VERSION_1_3A:
487 return "1.3a";
488 case CEC_VERSION_1_4:
489 return "1.4";
490 default:
491 return "unknown";
492 }
03ae897d
LOK
493}
494
495const char *CLibCEC::ToString(const cec_power_status status)
496{
004b8382
LOK
497 switch (status)
498 {
499 case CEC_POWER_STATUS_ON:
500 return "on";
501 case CEC_POWER_STATUS_STANDBY:
502 return "standby";
503 case CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY:
504 return "in transition from on to standby";
505 case CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON:
506 return "in transition from standby to on";
507 default:
508 return "unknown";
509 }
03ae897d
LOK
510}
511
512const char *CLibCEC::ToString(const cec_logical_address address)
513{
004b8382
LOK
514 switch(address)
515 {
516 case CECDEVICE_AUDIOSYSTEM:
517 return "Audio";
518 case CECDEVICE_BROADCAST:
519 return "Broadcast";
520 case CECDEVICE_FREEUSE:
521 return "Free use";
522 case CECDEVICE_PLAYBACKDEVICE1:
523 return "Playback 1";
524 case CECDEVICE_PLAYBACKDEVICE2:
525 return "Playback 2";
526 case CECDEVICE_PLAYBACKDEVICE3:
527 return "Playback 3";
528 case CECDEVICE_RECORDINGDEVICE1:
529 return "Recorder 1";
530 case CECDEVICE_RECORDINGDEVICE2:
531 return "Recorder 2";
532 case CECDEVICE_RECORDINGDEVICE3:
533 return "Recorder 3";
534 case CECDEVICE_RESERVED1:
535 return "Reserved 1";
536 case CECDEVICE_RESERVED2:
537 return "Reserved 2";
538 case CECDEVICE_TUNER1:
539 return "Tuner 1";
540 case CECDEVICE_TUNER2:
541 return "Tuner 2";
542 case CECDEVICE_TUNER3:
543 return "Tuner 3";
544 case CECDEVICE_TUNER4:
545 return "Tuner 4";
546 case CECDEVICE_TV:
547 return "TV";
548 default:
549 return "unknown";
550 }
03ae897d
LOK
551}
552
553const char *CLibCEC::ToString(const cec_deck_control_mode mode)
554{
004b8382
LOK
555 switch (mode)
556 {
557 case CEC_DECK_CONTROL_MODE_SKIP_FORWARD_WIND:
558 return "skip forward wind";
559 case CEC_DECK_CONTROL_MODE_EJECT:
560 return "eject";
561 case CEC_DECK_CONTROL_MODE_SKIP_REVERSE_REWIND:
562 return "reverse rewind";
563 case CEC_DECK_CONTROL_MODE_STOP:
564 return "stop";
565 default:
566 return "unknown";
567 }
03ae897d
LOK
568}
569
570const char *CLibCEC::ToString(const cec_deck_info status)
571{
004b8382
LOK
572 switch (status)
573 {
574 case CEC_DECK_INFO_PLAY:
575 return "play";
576 case CEC_DECK_INFO_RECORD:
577 return "record";
578 case CEC_DECK_INFO_PLAY_REVERSE:
579 return "play reverse";
580 case CEC_DECK_INFO_STILL:
581 return "still";
582 case CEC_DECK_INFO_SLOW:
583 return "slow";
584 case CEC_DECK_INFO_SLOW_REVERSE:
585 return "slow reverse";
586 case CEC_DECK_INFO_FAST_FORWARD:
587 return "fast forward";
588 case CEC_DECK_INFO_FAST_REVERSE:
589 return "fast reverse";
590 case CEC_DECK_INFO_NO_MEDIA:
591 return "no media";
592 case CEC_DECK_INFO_STOP:
593 return "stop";
594 case CEC_DECK_INFO_SKIP_FORWARD_WIND:
595 return "info skip forward wind";
596 case CEC_DECK_INFO_SKIP_REVERSE_REWIND:
597 return "info skip reverse rewind";
598 case CEC_DECK_INFO_INDEX_SEARCH_FORWARD:
599 return "info index search forward";
600 case CEC_DECK_INFO_INDEX_SEARCH_REVERSE:
601 return "info index search reverse";
602 case CEC_DECK_INFO_OTHER_STATUS:
603 return "other";
604 case CEC_DECK_INFO_OTHER_STATUS_LG:
605 return "LG other";
606 default:
607 return "unknown";
608 }
03ae897d
LOK
609}
610
611const char *CLibCEC::ToString(const cec_opcode opcode)
612{
004b8382
LOK
613 switch (opcode)
614 {
615 case CEC_OPCODE_ACTIVE_SOURCE:
616 return "active source";
617 case CEC_OPCODE_IMAGE_VIEW_ON:
618 return "image view on";
619 case CEC_OPCODE_TEXT_VIEW_ON:
620 return "text view on";
621 case CEC_OPCODE_INACTIVE_SOURCE:
622 return "inactive source";
623 case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
624 return "request active source";
625 case CEC_OPCODE_ROUTING_CHANGE:
626 return "routing change";
627 case CEC_OPCODE_ROUTING_INFORMATION:
628 return "routing information";
629 case CEC_OPCODE_SET_STREAM_PATH:
630 return "set stream path";
631 case CEC_OPCODE_STANDBY:
632 return "standby";
633 case CEC_OPCODE_RECORD_OFF:
634 return "record off";
635 case CEC_OPCODE_RECORD_ON:
636 return "record on";
637 case CEC_OPCODE_RECORD_STATUS:
638 return "record status";
639 case CEC_OPCODE_RECORD_TV_SCREEN:
640 return "record tv screen";
641 case CEC_OPCODE_CLEAR_ANALOGUE_TIMER:
642 return "clear analogue timer";
643 case CEC_OPCODE_CLEAR_DIGITAL_TIMER:
644 return "clear digital timer";
645 case CEC_OPCODE_CLEAR_EXTERNAL_TIMER:
646 return "clear external timer";
647 case CEC_OPCODE_SET_ANALOGUE_TIMER:
648 return "set analogue timer";
649 case CEC_OPCODE_SET_DIGITAL_TIMER:
650 return "set digital timer";
651 case CEC_OPCODE_SET_EXTERNAL_TIMER:
652 return "set external timer";
653 case CEC_OPCODE_SET_TIMER_PROGRAM_TITLE:
654 return "set timer program title";
655 case CEC_OPCODE_TIMER_CLEARED_STATUS:
656 return "timer cleared status";
657 case CEC_OPCODE_TIMER_STATUS:
658 return "timer status";
659 case CEC_OPCODE_CEC_VERSION:
660 return "cec version";
661 case CEC_OPCODE_GET_CEC_VERSION:
662 return "get cec version";
663 case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
664 return "give physical address";
665 case CEC_OPCODE_GET_MENU_LANGUAGE:
666 return "get menu language";
667 case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS:
668 return "report physical address";
669 case CEC_OPCODE_SET_MENU_LANGUAGE:
670 return "set menu language";
671 case CEC_OPCODE_DECK_CONTROL:
672 return "deck control";
673 case CEC_OPCODE_DECK_STATUS:
674 return "deck status";
675 case CEC_OPCODE_GIVE_DECK_STATUS:
676 return "give deck status";
677 case CEC_OPCODE_PLAY:
678 return "play";
679 case CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS:
680 return "give tuner status";
681 case CEC_OPCODE_SELECT_ANALOGUE_SERVICE:
682 return "select analogue service";
683 case CEC_OPCODE_SELECT_DIGITAL_SERVICE:
684 return "set digital service";
685 case CEC_OPCODE_TUNER_DEVICE_STATUS:
686 return "tuner device status";
687 case CEC_OPCODE_TUNER_STEP_DECREMENT:
688 return "tuner step decrement";
689 case CEC_OPCODE_TUNER_STEP_INCREMENT:
690 return "tuner step increment";
691 case CEC_OPCODE_DEVICE_VENDOR_ID:
692 return "device vendor id";
693 case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
694 return "give device vendor id";
695 case CEC_OPCODE_VENDOR_COMMAND:
696 return "vendor command";
697 case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
698 return "vendor command with id";
699 case CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
700 return "vendor remote button down";
701 case CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP:
702 return "vendor remote button up";
703 case CEC_OPCODE_SET_OSD_STRING:
704 return "set osd string";
705 case CEC_OPCODE_GIVE_OSD_NAME:
706 return "give osd name";
707 case CEC_OPCODE_SET_OSD_NAME:
708 return "set osd name";
709 case CEC_OPCODE_MENU_REQUEST:
710 return "menu request";
711 case CEC_OPCODE_MENU_STATUS:
712 return "menu status";
713 case CEC_OPCODE_USER_CONTROL_PRESSED:
714 return "user control pressed";
715 case CEC_OPCODE_USER_CONTROL_RELEASE:
716 return "user control release";
717 case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
718 return "give device power status";
719 case CEC_OPCODE_REPORT_POWER_STATUS:
720 return "report power status";
721 case CEC_OPCODE_FEATURE_ABORT:
722 return "feature abort";
723 case CEC_OPCODE_ABORT:
724 return "abort";
725 case CEC_OPCODE_GIVE_AUDIO_STATUS:
726 return "give audio status";
727 case CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS:
728 return "give audio mode status";
729 case CEC_OPCODE_REPORT_AUDIO_STATUS:
730 return "report audio status";
731 case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE:
732 return "set system audio mode";
733 case CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST:
734 return "system audio mode request";
735 case CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS:
736 return "system audio mode status";
737 case CEC_OPCODE_SET_AUDIO_RATE:
738 return "set audio rate";
739 case CEC_OPCODE_START_ARC:
740 return "start ARC";
741 case CEC_OPCODE_REPORT_ARC_STARTED:
742 return "report ARC started";
743 case CEC_OPCODE_REPORT_ARC_ENDED:
744 return "report ARC ended";
745 case CEC_OPCODE_REQUEST_ARC_START:
746 return "request ARC start";
747 case CEC_OPCODE_REQUEST_ARC_END:
748 return "request ARC end";
749 case CEC_OPCODE_END_ARC:
750 return "end ARC";
751 case CEC_OPCODE_CDC:
752 return "CDC";
753 case CEC_OPCODE_NONE:
754 return "poll";
755 default:
756 return "UNKNOWN";
757 }
03ae897d
LOK
758}
759
760const char *CLibCEC::ToString(const cec_system_audio_status mode)
761{
004b8382
LOK
762 switch(mode)
763 {
764 case CEC_SYSTEM_AUDIO_STATUS_ON:
765 return "on";
766 case CEC_SYSTEM_AUDIO_STATUS_OFF:
767 return "off";
768 default:
769 return "unknown";
770 }
03ae897d
LOK
771}
772
004b8382 773const char *CLibCEC::ToString(const cec_audio_status UNUSED(status))
03ae897d 774{
004b8382
LOK
775 // TODO this is a mask
776 return "TODO";
03ae897d
LOK
777}
778
779const char *CLibCEC::ToString(const cec_vendor_id vendor)
780{
004b8382
LOK
781 switch (vendor)
782 {
783 case CEC_VENDOR_SAMSUNG:
784 return "Samsung";
785 case CEC_VENDOR_LG:
786 return "LG";
787 case CEC_VENDOR_PANASONIC:
788 return "Panasonic";
789 case CEC_VENDOR_PIONEER:
790 return "Pioneer";
791 case CEC_VENDOR_ONKYO:
792 return "Onkyo";
793 case CEC_VENDOR_YAMAHA:
794 return "Yamaha";
795 case CEC_VENDOR_PHILIPS:
796 return "Philips";
797 case CEC_VENDOR_SONY:
798 return "Sony";
799 case CEC_VENDOR_TOSHIBA:
800 return "Toshiba";
801 default:
802 return "Unknown";
803 }
03ae897d 804}
caca2d81
LOK
805
806const char *CLibCEC::ToString(const cec_client_version version)
807{
004b8382
LOK
808 switch (version)
809 {
810 case CEC_CLIENT_VERSION_PRE_1_5:
811 return "pre-1.5";
812 case CEC_CLIENT_VERSION_1_5_0:
813 return "1.5.0";
814 case CEC_CLIENT_VERSION_1_5_1:
815 return "1.5.1";
816 case CEC_CLIENT_VERSION_1_5_2:
817 return "1.5.2";
818 case CEC_CLIENT_VERSION_1_5_3:
819 return "1.5.3";
820 case CEC_CLIENT_VERSION_1_6_0:
821 return "1.6.0";
822 case CEC_CLIENT_VERSION_1_6_1:
823 return "1.6.1";
824 case CEC_CLIENT_VERSION_1_6_2:
825 return "1.6.2";
5f2f3609
LOK
826 case CEC_CLIENT_VERSION_1_6_3:
827 return "1.6.3";
004b8382
LOK
828 default:
829 return "Unknown";
830 }
caca2d81 831}
d40928b5 832
3efda01a
LOK
833const char *CLibCEC::ToString(const cec_server_version version)
834{
004b8382
LOK
835 switch (version)
836 {
837 case CEC_SERVER_VERSION_PRE_1_5:
838 return "pre-1.5";
839 case CEC_SERVER_VERSION_1_5_0:
840 return "1.5.0";
841 case CEC_SERVER_VERSION_1_5_1:
842 return "1.5.1";
843 case CEC_SERVER_VERSION_1_5_2:
844 return "1.5.2";
845 case CEC_SERVER_VERSION_1_5_3:
846 return "1.5.3";
847 case CEC_SERVER_VERSION_1_6_0:
848 return "1.6.0";
849 case CEC_SERVER_VERSION_1_6_1:
850 return "1.6.1";
851 case CEC_SERVER_VERSION_1_6_2:
852 return "1.6.2";
5f2f3609
LOK
853 case CEC_SERVER_VERSION_1_6_3:
854 return "1.6.3";
004b8382
LOK
855 default:
856 return "Unknown";
857 }
3efda01a
LOK
858}
859
004b8382 860void CLibCEC::CheckKeypressTimeout(void)
a75e3a5a 861{
004b8382
LOK
862 // check all clients
863 for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
864 (*it)->CheckKeypressTimeout();
a75e3a5a
LOK
865}
866
004b8382 867void CLibCEC::AddLog(const cec_log_level level, const char *strFormat, ...)
d40928b5 868{
004b8382
LOK
869 CStdString strLog;
870
c0152c09 871 // format the message
004b8382
LOK
872 va_list argList;
873 va_start(argList, strFormat);
874 strLog.FormatV(strFormat, argList);
875 va_end(argList);
876
877 cec_log_message message;
878 message.level = level;
879 message.time = GetTimeMs() - m_iStartTime;
880 snprintf(message.message, sizeof(message.message), "%s", strLog.c_str());
881
882 // send the message to all clients
883 for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
884 (*it)->AddLog(message);
224ea877
LOK
885}
886
004b8382 887void CLibCEC::Alert(const libcec_alert type, const libcec_parameter &param)
30b4aac0 888{
004b8382
LOK
889 // send the alert to all clients
890 for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
891 (*it)->Alert(type, param);
30b4aac0
LOK
892}
893
004b8382 894bool CLibCEC::SetActiveView(void)
224ea877 895{
004b8382
LOK
896 AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
897 return SetActiveSource();
224ea877
LOK
898}
899
004b8382 900bool CLibCEC::EnablePhysicalAddressDetection(void)
224ea877 901{
004b8382
LOK
902 AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
903 return true;
224ea877 904}
3efda01a 905
c0152c09 906CCECClient *CLibCEC::RegisterClient(libcec_configuration &configuration)
3efda01a 907{
004b8382
LOK
908 if (!m_cec)
909 return NULL;
910
c0152c09 911 // create a new client instance
004b8382
LOK
912 CCECClient *newClient = new CCECClient(m_cec, configuration);
913 if (!newClient)
914 return NULL;
004b8382 915 m_clients.push_back(newClient);
c0152c09
LOK
916
917 // if the default client isn't set, set it
004b8382
LOK
918 if (!m_client)
919 m_client = newClient;
920
c0152c09 921 // register the new client
0b8c7eab 922 if (m_cec->CECInitialised())
004b8382
LOK
923 m_cec->RegisterClient(newClient);
924
99aeafb9 925 return newClient;
3efda01a 926}
c9549d35 927
004b8382 928void CLibCEC::UnregisterClients(void)
c9549d35 929{
c0152c09
LOK
930 if (m_cec)
931 m_cec->UnregisterClients();
932
004b8382 933 m_clients.clear();
c0152c09 934
004b8382
LOK
935 delete m_client;
936 m_client = NULL;
c9549d35 937}
9878069e 938
004b8382 939void * CECInitialise(libcec_configuration *configuration)
9878069e 940{
004b8382
LOK
941 if (!configuration)
942 return NULL;
943
c0152c09 944 // create a new libCEC instance
c30acafa 945 CLibCEC *lib = new CLibCEC(NULL);
c0152c09
LOK
946
947 // register a new client
99aeafb9 948 CCECClient *client(NULL);
c0152c09
LOK
949 if (lib && configuration)
950 client = lib->RegisterClient(*configuration);
99aeafb9 951
c0152c09 952 // update the current configuration
99aeafb9 953 if (client)
c0152c09 954 client->GetCurrentConfiguration(*configuration);
99aeafb9
LOK
955
956 // ensure that the correct server version is set
957 configuration->serverVersion = LIBCEC_VERSION_CURRENT;
004b8382
LOK
958
959 return static_cast< void* > (lib);
9878069e 960}
209b7a5c 961
004b8382 962void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types, uint16_t iPhysicalAddress /* = 0 */)
209b7a5c 963{
004b8382 964 libcec_configuration configuration;
004b8382
LOK
965
966 // client version < 1.5.0
967 snprintf(configuration.strDeviceName, 13, "%s", strDeviceName);
968 configuration.deviceTypes = types;
969 configuration.iPhysicalAddress = iPhysicalAddress;
970
971 if (configuration.deviceTypes.IsEmpty())
972 configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
973
974 return CECInitialise(&configuration);
209b7a5c
LOK
975}
976
004b8382 977bool CECStartBootloader(void)
209b7a5c 978{
004b8382
LOK
979 bool bReturn(false);
980 cec_adapter deviceList[1];
981 if (CUSBCECAdapterDetection::FindAdapters(deviceList, 1) > 0)
209b7a5c 982 {
004b8382
LOK
983 CUSBCECAdapterCommunication comm(NULL, deviceList[0].comm);
984 CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT);
985 while (timeout.TimeLeft() > 0 && (bReturn = comm.Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false)
209b7a5c 986 {
004b8382
LOK
987 comm.Close();
988 CEvent::Sleep(500);
209b7a5c 989 }
004b8382
LOK
990 if (comm.IsOpen())
991 bReturn = comm.StartBootloader();
209b7a5c 992 }
004b8382
LOK
993
994 return bReturn;
995}
996
997void CECDestroy(CEC::ICECAdapter *instance)
998{
999 delete instance;
209b7a5c 1000}
f80cd208 1001
b32ffd87 1002bool CLibCEC::GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
f80cd208
LOK
1003{
1004 if (m_cec->IsRunning())
1005 return false;
004b8382 1006
f80cd208 1007 return m_cec->GetDeviceInformation(strPort, config, iTimeoutMs);
a75e3a5a 1008}
c30acafa 1009
c0152c09 1010// no longer being used
c30acafa
LOK
1011void CLibCEC::AddKey(const cec_keypress &UNUSED(key)) {}
1012void CLibCEC::AddCommand(const cec_command &UNUSED(command)) {}
1013void CLibCEC::ConfigurationChanged(const libcec_configuration &UNUSED(config)) {}
1014void CLibCEC::SetCurrentButton(cec_user_control_code UNUSED(iButtonCode)) {}
1015CLibCEC *CLibCEC::GetInstance(void) { return NULL; }
1016void CLibCEC::SetInstance(CLibCEC *UNUSED(instance)) {}