1 /*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 *
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
27 *
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
32 */
33
34 #include "env.h"
35 #include "LibCEC.h"
36
37 #include "adapter/AdapterFactory.h"
38 #include "adapter/AdapterCommunication.h"
39 #include "CECProcessor.h"
40 #include "devices/CECAudioSystem.h"
41 #include "devices/CECBusDevice.h"
42 #include "devices/CECPlaybackDevice.h"
43 #include "devices/CECTV.h"
44 #include "p8-platform/util/timeutils.h"
45 #include "p8-platform/util/util.h"
46 #include <stdio.h>
47 #include <stdlib.h>
48
49 #include "CECClient.h"
50
51 using namespace CEC;
52 using namespace P8PLATFORM;
53
CLibCEC(void)54 CLibCEC::CLibCEC(void) :
55 m_iStartTime(GetTimeMs()),
56 m_client(nullptr)
57 {
58 m_cec = new CCECProcessor(this);
59 }
60
~CLibCEC(void)61 CLibCEC::~CLibCEC(void)
62 {
63 // unregister all clients
64 if (m_cec && m_cec->IsRunning())
65 m_cec->UnregisterClients();
66
67 m_clients.clear();
68
69 // delete the adapter connection
70 SAFE_DELETE(m_cec);
71
72 // delete active client
73 m_client.reset();
74 }
75
Open(const char * strPort,uint32_t iTimeoutMs)76 bool CLibCEC::Open(const char *strPort, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
77 {
78 if (!m_cec || !strPort)
79 return false;
80
81 // open a new connection
82 if (!m_cec->Start(strPort, CEC_SERIAL_DEFAULT_BAUDRATE, iTimeoutMs))
83 {
84 AddLog(CEC_LOG_ERROR, "could not start CEC communications");
85 return false;
86 }
87
88 // register all clients
89 for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
90 {
91 if (!m_cec->RegisterClient(*it))
92 {
93 AddLog(CEC_LOG_ERROR, "failed to register a CEC client");
94 return false;
95 }
96 }
97
98 return true;
99 }
100
Close(void)101 void CLibCEC::Close(void)
102 {
103 if (!m_cec)
104 return;
105
106 // unregister all clients
107 m_cec->UnregisterClients();
108
109 // close the connection
110 m_cec->Close();
111 }
112
FindAdapters(cec_adapter * deviceList,uint8_t iBufSize,const char * strDevicePath)113 int8_t CLibCEC::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = nullptr */)
114 {
115 return CAdapterFactory(this).FindAdapters(deviceList, iBufSize, strDevicePath);
116 }
117
StartBootloader(void)118 bool CLibCEC::StartBootloader(void)
119 {
120 return m_cec ? m_cec->StartBootloader() : false;
121 }
122
PingAdapter(void)123 bool CLibCEC::PingAdapter(void)
124 {
125 return m_client ? m_client->PingAdapter() : false;
126 }
127
128 #if CEC_LIB_VERSION_MAJOR >= 5
SetCallbacks(ICECCallbacks * callbacks,void * cbParam)129 bool CLibCEC::SetCallbacks(ICECCallbacks *callbacks, void *cbParam)
130 {
131 return !!m_client ? m_client->EnableCallbacks(cbParam, callbacks) : false;
132 }
133
DisableCallbacks(void)134 bool CLibCEC::DisableCallbacks(void)
135 {
136 return !!m_client ? m_client->EnableCallbacks(nullptr, nullptr) : false;
137 }
138
EnableCallbacks(void * cbParam,ICECCallbacks * callbacks)139 bool CLibCEC::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks)
140 {
141 return SetCallbacks(callbacks, cbParam);
142 }
143 #else
EnableCallbacks(void * cbParam,ICECCallbacks * callbacks)144 bool CLibCEC::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks)
145 {
146 return !!m_client ? m_client->EnableCallbacks(cbParam, callbacks) : false;
147 }
148 #endif
149
GetCurrentConfiguration(libcec_configuration * configuration)150 bool CLibCEC::GetCurrentConfiguration(libcec_configuration *configuration)
151 {
152 return m_client ? m_client->GetCurrentConfiguration(*configuration) : false;
153 }
154
SetConfiguration(const libcec_configuration * configuration)155 bool CLibCEC::SetConfiguration(const libcec_configuration *configuration)
156 {
157 return m_client ? m_client->SetConfiguration(*configuration) : false;
158 }
159
160 #if CEC_LIB_VERSION_MAJOR >= 5
CanSaveConfiguration(void)161 bool CLibCEC::CanSaveConfiguration(void)
162 #else
163 bool CLibCEC::CanPersistConfiguration(void)
164 #endif
165 {
166 return m_client ? m_client->CanSaveConfiguration() : false;
167 }
168
169 #if CEC_LIB_VERSION_MAJOR < 5
PersistConfiguration(libcec_configuration * configuration)170 bool CLibCEC::PersistConfiguration(libcec_configuration *configuration)
171 {
172 return SetConfiguration(configuration);
173 }
174 #endif
175
RescanActiveDevices(void)176 void CLibCEC::RescanActiveDevices(void)
177 {
178 if (m_client)
179 m_client->RescanActiveDevices();
180 }
181
IsLibCECActiveSource(void)182 bool CLibCEC::IsLibCECActiveSource(void)
183 {
184 return m_client ? m_client->IsLibCECActiveSource() : false;
185 }
186
Transmit(const cec_command & data)187 bool CLibCEC::Transmit(const cec_command &data)
188 {
189 return m_client ? m_client->Transmit(data, false) : false;
190 }
191
SetLogicalAddress(cec_logical_address iLogicalAddress)192 bool CLibCEC::SetLogicalAddress(cec_logical_address iLogicalAddress)
193 {
194 return m_client ? m_client->SetLogicalAddress(iLogicalAddress) : false;
195 }
196
SetPhysicalAddress(uint16_t iPhysicalAddress)197 bool CLibCEC::SetPhysicalAddress(uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */)
198 {
199 return m_client ? m_client->SetPhysicalAddress(iPhysicalAddress) : false;
200 }
201
SetHDMIPort(cec_logical_address iBaseDevice,uint8_t iPort)202 bool CLibCEC::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
203 {
204 return m_client ? m_client->SetHDMIPort(iBaseDevice, iPort) : false;
205 }
206
PowerOnDevices(cec_logical_address address)207 bool CLibCEC::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */)
208 {
209 return m_client ? m_client->SendPowerOnDevices(address) : false;
210 }
211
StandbyDevices(cec_logical_address address)212 bool CLibCEC::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */)
213 {
214 return m_client ? m_client->SendStandbyDevices(address) : false;
215 }
216
SetActiveSource(cec_device_type type)217 bool CLibCEC::SetActiveSource(cec_device_type type /* = CEC_DEVICE_TYPE_RESERVED */)
218 {
219 return m_client ? m_client->SendSetActiveSource(type) : false;
220 }
221
SetDeckControlMode(cec_deck_control_mode mode,bool bSendUpdate)222 bool CLibCEC::SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate /* = true */)
223 {
224 return m_client ? m_client->SendSetDeckControlMode(mode, bSendUpdate) : false;
225 }
226
SetDeckInfo(cec_deck_info info,bool bSendUpdate)227 bool CLibCEC::SetDeckInfo(cec_deck_info info, bool bSendUpdate /* = true */)
228 {
229 return m_client ? m_client->SendSetDeckInfo(info, bSendUpdate) : false;
230 }
231
SetInactiveView(void)232 bool CLibCEC::SetInactiveView(void)
233 {
234 return m_client ? m_client->SendSetInactiveView() : false;
235 }
236
SetMenuState(cec_menu_state state,bool bSendUpdate)237 bool CLibCEC::SetMenuState(cec_menu_state state, bool bSendUpdate /* = true */)
238 {
239 return m_client ? m_client->SendSetMenuState(state, bSendUpdate) : false;
240 }
241
SetOSDString(cec_logical_address iLogicalAddress,cec_display_control duration,const char * strMessage)242 bool CLibCEC::SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage)
243 {
244 return m_client ? m_client->SendSetOSDString(iLogicalAddress, duration, strMessage) : false;
245 }
246
SwitchMonitoring(bool bEnable)247 bool CLibCEC::SwitchMonitoring(bool bEnable)
248 {
249 return m_client ? m_client->SwitchMonitoring(bEnable) : false;
250 }
251
GetDeviceCecVersion(cec_logical_address iAddress)252 cec_version CLibCEC::GetDeviceCecVersion(cec_logical_address iAddress)
253 {
254 return m_client ? m_client->GetDeviceCecVersion(iAddress) : CEC_VERSION_UNKNOWN;
255 }
256
GetDeviceMenuLanguage(cec_logical_address iAddress)257 std::string CLibCEC::GetDeviceMenuLanguage(cec_logical_address iAddress)
258 {
259 return !!m_client ? m_client->GetDeviceMenuLanguage(iAddress) : "???";
260 }
261
GetDeviceVendorId(cec_logical_address iAddress)262 uint32_t CLibCEC::GetDeviceVendorId(cec_logical_address iAddress)
263 {
264 return m_client ? m_client->GetDeviceVendorId(iAddress) : (uint32_t)CEC_VENDOR_UNKNOWN;
265 }
266
GetDevicePhysicalAddress(cec_logical_address iAddress)267 uint16_t CLibCEC::GetDevicePhysicalAddress(cec_logical_address iAddress)
268 {
269 return m_client ? m_client->GetDevicePhysicalAddress(iAddress) : CEC_INVALID_PHYSICAL_ADDRESS;
270 }
271
GetDevicePowerStatus(cec_logical_address iAddress)272 cec_power_status CLibCEC::GetDevicePowerStatus(cec_logical_address iAddress)
273 {
274 return m_client ? m_client->GetDevicePowerStatus(iAddress) : CEC_POWER_STATUS_UNKNOWN;
275 }
276
PollDevice(cec_logical_address iAddress)277 bool CLibCEC::PollDevice(cec_logical_address iAddress)
278 {
279 return m_client ? m_client->PollDevice(iAddress) : false;
280 }
281
GetActiveDevices(void)282 cec_logical_addresses CLibCEC::GetActiveDevices(void)
283 {
284 cec_logical_addresses addresses;
285 addresses.Clear();
286 if (m_client)
287 addresses = m_client->GetActiveDevices();
288 return addresses;
289 }
290
IsActiveDevice(cec_logical_address iAddress)291 bool CLibCEC::IsActiveDevice(cec_logical_address iAddress)
292 {
293 return m_client ? m_client->IsActiveDevice(iAddress) : false;
294 }
295
IsActiveDeviceType(cec_device_type type)296 bool CLibCEC::IsActiveDeviceType(cec_device_type type)
297 {
298 return m_client ? m_client->IsActiveDeviceType(type) : false;
299 }
300
VolumeUp(bool bSendRelease)301 uint8_t CLibCEC::VolumeUp(bool bSendRelease /* = true */)
302 {
303 return m_client ? m_client->SendVolumeUp(bSendRelease) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
304 }
305
VolumeDown(bool bSendRelease)306 uint8_t CLibCEC::VolumeDown(bool bSendRelease /* = true */)
307 {
308 return m_client ? m_client->SendVolumeDown(bSendRelease) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
309 }
310
311 #if CEC_LIB_VERSION_MAJOR >= 5
MuteAudio(void)312 uint8_t CLibCEC::MuteAudio(void)
313 {
314 return !!m_client ?
315 m_client->SendMuteAudio() :
316 (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
317 }
318 #endif
319
SendKeypress(cec_logical_address iDestination,cec_user_control_code key,bool bWait)320 bool CLibCEC::SendKeypress(cec_logical_address iDestination, cec_user_control_code key, bool bWait /* = true */)
321 {
322 return m_client ? m_client->SendKeypress(iDestination, key, bWait) : false;
323 }
324
SendKeyRelease(cec_logical_address iDestination,bool bWait)325 bool CLibCEC::SendKeyRelease(cec_logical_address iDestination, bool bWait /* = true */)
326 {
327 return m_client ? m_client->SendKeyRelease(iDestination, bWait) : false;
328 }
329
GetDeviceOSDName(cec_logical_address iAddress)330 std::string CLibCEC::GetDeviceOSDName(cec_logical_address iAddress)
331 {
332 return !!m_client ?
333 m_client->GetDeviceOSDName(iAddress) :
334 "";
335 }
336
GetActiveSource(void)337 cec_logical_address CLibCEC::GetActiveSource(void)
338 {
339 return m_client ? m_client->GetActiveSource() : CECDEVICE_UNKNOWN;
340 }
341
IsActiveSource(cec_logical_address iAddress)342 bool CLibCEC::IsActiveSource(cec_logical_address iAddress)
343 {
344 return m_client ? m_client->IsActiveSource(iAddress) : false;
345 }
SetStreamPath(cec_logical_address iAddress)346 bool CLibCEC::SetStreamPath(cec_logical_address iAddress)
347 {
348 return m_client ? m_client->SetStreamPath(iAddress) : false;
349 }
350
SetStreamPath(uint16_t iPhysicalAddress)351 bool CLibCEC::SetStreamPath(uint16_t iPhysicalAddress)
352 {
353 return m_client ? m_client->SetStreamPath(iPhysicalAddress) : false;
354 }
355
GetLogicalAddresses(void)356 cec_logical_addresses CLibCEC::GetLogicalAddresses(void)
357 {
358 cec_logical_addresses addresses;
359 addresses.Clear();
360 if (m_client)
361 addresses = m_client->GetLogicalAddresses();
362 return addresses;
363 }
364
GetType(cec_logical_address address)365 cec_device_type CLibCEC::GetType(cec_logical_address address)
366 {
367 return CCECTypeUtils::GetType(address);
368 }
369
GetMaskForType(cec_logical_address address)370 uint16_t CLibCEC::GetMaskForType(cec_logical_address address)
371 {
372 return CCECTypeUtils::GetMaskForType(address);
373 }
374
GetMaskForType(cec_device_type type)375 uint16_t CLibCEC::GetMaskForType(cec_device_type type)
376 {
377 return CCECTypeUtils::GetMaskForType(type);
378 }
379
IsValidPhysicalAddress(uint16_t iPhysicalAddress)380 bool CLibCEC::IsValidPhysicalAddress(uint16_t iPhysicalAddress)
381 {
382 return iPhysicalAddress >= CEC_MIN_PHYSICAL_ADDRESS &&
383 iPhysicalAddress <= CEC_MAX_PHYSICAL_ADDRESS;
384 }
385
CheckKeypressTimeout(void)386 uint16_t CLibCEC::CheckKeypressTimeout(void)
387 {
388 uint16_t timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
389 // check all clients
390 for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
391 {
392 uint16_t t = (*it)->CheckKeypressTimeout();
393 if (t < timeout)
394 timeout = t;
395 }
396 return timeout;
397 }
398
AddLog(const cec_log_level level,const char * strFormat,...)399 void CLibCEC::AddLog(const cec_log_level level, const char *strFormat, ...)
400 {
401 // format the message
402 va_list argList;
403 cec_log_message_cpp message;
404 message.level = level;
405 message.time = GetTimeMs() - m_iStartTime;
406 va_start(argList, strFormat);
407 message.message = StringUtils::FormatV(strFormat, argList);
408 va_end(argList);
409
410 // send the message to all clients
411 CLockObject lock(m_mutex);
412 for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
413 (*it)->AddLog(message);
414 }
415
AddCommand(const cec_command & command)416 void CLibCEC::AddCommand(const cec_command &command)
417 {
418 // send the command to all clients
419 CLockObject lock(m_mutex);
420 for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
421 (*it)->QueueAddCommand(command);
422 }
423
Alert(const libcec_alert type,const libcec_parameter & param)424 void CLibCEC::Alert(const libcec_alert type, const libcec_parameter ¶m)
425 {
426 // send the alert to all clients
427 CLockObject lock(m_mutex);
428 for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
429 (*it)->Alert(type, param);
430 }
431
RegisterClient(libcec_configuration & configuration)432 CECClientPtr CLibCEC::RegisterClient(libcec_configuration &configuration)
433 {
434 if (!m_cec)
435 return CECClientPtr();
436 if (configuration.clientVersion < LIBCEC_VERSION_TO_UINT(4, 0, 0))
437 {
438 AddLog(CEC_LOG_ERROR, "failed to register a new CEC client: client version %s is no longer supported", CCECTypeUtils::VersionToString(configuration.clientVersion).c_str());
439 return CECClientPtr();
440 }
441
442 // create a new client instance
443 CECClientPtr newClient = CECClientPtr(new CCECClient(m_cec, configuration));
444 if (!newClient)
445 return newClient;
446 m_clients.push_back(newClient);
447
448 // if the default client isn't set, set it
449 if (!m_client)
450 m_client = newClient;
451
452 // register the new client
453 if (m_cec->CECInitialised())
454 {
455 if (!m_cec->RegisterClient(newClient))
456 newClient = CECClientPtr();
457 else
458 {
459 // update the current configuration
460 newClient->GetCurrentConfiguration(configuration);
461 }
462 }
463
464 return newClient;
465 }
466
CECInitialise(libcec_configuration * configuration)467 ICECAdapter* CECInitialise(libcec_configuration *configuration)
468 {
469 if (!configuration)
470 return nullptr;
471
472 // create a new libCEC instance
473 CLibCEC *lib = new CLibCEC;
474
475 // register a new client
476 CECClientPtr client;
477 return (!!lib && !!lib->RegisterClient(*configuration)) ?
478 static_cast<ICECAdapter*> (lib) :
479 nullptr;
480 }
481
CECStartBootloader(void)482 bool CECStartBootloader(void)
483 {
484 bool bReturn(false);
485 cec_adapter deviceList[1];
486 if (CAdapterFactory(nullptr).FindAdapters(deviceList, 1, 0) > 0)
487 {
488 CAdapterFactory factory(nullptr);
489 IAdapterCommunication *comm = factory.GetInstance(deviceList[0].comm);
490 if (comm)
491 {
492 CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT);
493 while (timeout.TimeLeft() > 0 &&
494 (bReturn = comm->Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false)
495 {
496 comm->Close();
497 CEvent::Sleep(500);
498 }
499 if (comm->IsOpen())
500 bReturn = comm->StartBootloader();
501
502 delete comm;
503 }
504 }
505
506 return bReturn;
507 }
508
CECDestroy(CEC::ICECAdapter * instance)509 void CECDestroy(CEC::ICECAdapter *instance)
510 {
511 SAFE_DELETE(instance);
512 }
513
GetDeviceInformation(const char * strPort,libcec_configuration * config,uint32_t iTimeoutMs)514 bool CLibCEC::GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
515 {
516 if (m_cec->IsRunning())
517 return false;
518
519 return m_cec->GetDeviceInformation(strPort, config, iTimeoutMs);
520 }
521
GetLibInfo(void)522 const char *CLibCEC::GetLibInfo(void)
523 {
524 #ifndef LIB_INFO
525 #ifdef _WIN32
526 #define FEATURES "'P8 USB' 'P8 USB detect'"
527 #ifdef _WIN64
528 #define HOST_TYPE "Windows (x64)"
529 #else
530 #define HOST_TYPE "Windows (x86)"
531 #endif
532 #else
533 #define HOST_TYPE "unknown"
534 #define FEATURES "unknown"
535 #endif
536
537 return "host: " HOST_TYPE ", features: " FEATURES ", compiled: " __DATE__;
538 #else
539 return LIB_INFO;
540 #endif
541 }
542
InitVideoStandalone(void)543 void CLibCEC::InitVideoStandalone(void)
544 {
545 CAdapterFactory::InitVideoStandalone();
546 }
GetAdapterVendorId(void) const547 uint16_t CLibCEC::GetAdapterVendorId(void) const
548 {
549 return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterVendorId() : 0;
550 }
551
GetAdapterProductId(void) const552 uint16_t CLibCEC::GetAdapterProductId(void) const
553 {
554 return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterProductId() : 0;
555 }
556
AudioToggleMute(void)557 uint8_t CLibCEC::AudioToggleMute(void)
558 {
559 return m_client ? m_client->AudioToggleMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
560 }
561
AudioMute(void)562 uint8_t CLibCEC::AudioMute(void)
563 {
564 return m_client ? m_client->AudioMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
565 }
566
AudioUnmute(void)567 uint8_t CLibCEC::AudioUnmute(void)
568 {
569 return m_client ? m_client->AudioUnmute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
570 }
571
AudioStatus(void)572 uint8_t CLibCEC::AudioStatus(void)
573 {
574 return m_client ? m_client->AudioStatus() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
575 }
576
DetectAdapters(cec_adapter_descriptor * deviceList,uint8_t iBufSize,const char * strDevicePath,bool bQuickScan)577 int8_t CLibCEC::DetectAdapters(cec_adapter_descriptor *deviceList, uint8_t iBufSize, const char *strDevicePath /* = nullptr */, bool bQuickScan /* = false */)
578 {
579 int8_t iAdaptersFound = CAdapterFactory(this).DetectAdapters(deviceList, iBufSize, strDevicePath);
580 if (!bQuickScan)
581 {
582 for (int8_t iPtr = 0; iPtr < iAdaptersFound; iPtr++)
583 {
584 libcec_configuration config;
585 GetDeviceInformation(deviceList[iPtr].strComName, &config);
586 deviceList[iPtr].iFirmwareVersion = config.iFirmwareVersion;
587 deviceList[iPtr].iPhysicalAddress = config.iPhysicalAddress;
588 deviceList[iPtr].iFirmwareBuildDate = config.iFirmwareBuildDate;
589 deviceList[iPtr].adapterType = config.adapterType;
590 }
591 }
592 return iAdaptersFound;
593 }
594
HexStrToInt(const std::string & data,uint8_t & value)595 inline bool HexStrToInt(const std::string& data, uint8_t& value)
596 {
597 int iTmp(0);
598 if (sscanf(data.c_str(), "%x", &iTmp) == 1)
599 {
600 if (iTmp > 256)
601 value = 255;
602 else if (iTmp < 0)
603 value = 0;
604 else
605 value = (uint8_t) iTmp;
606
607 return true;
608 }
609
610 return false;
611 }
612
CommandFromString(const char * strCommand)613 cec_command CLibCEC::CommandFromString(const char* strCommand)
614 {
615 std::vector<std::string> splitCommand = StringUtils::Split(strCommand, ":");
616 cec_command retval;
617 unsigned long tmpVal;
618
619 for (std::vector<std::string>::const_iterator it = splitCommand.begin(); it != splitCommand.end(); ++it)
620 {
621 tmpVal = strtoul((*it).c_str(), nullptr, 16);
622 if (tmpVal <= 0xFF)
623 retval.PushBack((uint8_t)tmpVal);
624 }
625
626 return retval;
627 }
628
PrintVersion(uint32_t version,char * buf,size_t bufSize)629 void CLibCEC::PrintVersion(uint32_t version, char* buf, size_t bufSize)
630 {
631 std::string strVersion = CCECTypeUtils::VersionToString(version);
632 snprintf(buf, bufSize, "%s", strVersion.c_str());
633 }
634
AudioEnable(bool enable)635 bool CLibCEC::AudioEnable(bool enable)
636 {
637 return !!m_client ?
638 m_client->AudioEnable(enable) :
639 false;
640 }
641
642 #if CEC_LIB_VERSION_MAJOR >= 5
GetStats(struct cec_adapter_stats * stats)643 bool CLibCEC::GetStats(struct cec_adapter_stats* stats)
644 {
645 return !!m_client ?
646 m_client->GetStats(stats) :
647 false;
648 }
649 #endif
650