cec: LG devices don't respond to CEC version requests (unsupported feature). set...
[deb_libcec.git] / src / lib / devices / CECBusDevice.cpp
CommitLineData
e9de9629
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.
e9de9629
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 "CECBusDevice.h"
eafa9d46
LOK
34#include "../CECProcessor.h"
35#include "../implementations/ANCommandHandler.h"
36#include "../implementations/CECCommandHandler.h"
37#include "../implementations/SLCommandHandler.h"
11621576 38#include "../implementations/VLCommandHandler.h"
5477a250 39#include "../LibCEC.h"
ba65909d 40#include "../platform/util/timeutils.h"
e9de9629
LOK
41
42using namespace CEC;
f00ff009 43using namespace PLATFORM;
e9de9629 44
03ae897d 45#define ToString(p) m_processor->ToString(p)
c4098482 46
e9de9629 47CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress) :
c4098482 48 m_type(CEC_DEVICE_TYPE_RESERVED),
e9de9629 49 m_iPhysicalAddress(iPhysicalAddress),
9dc04b07 50 m_iStreamPath(0),
e9de9629 51 m_iLogicalAddress(iLogicalAddress),
e55f3f70 52 m_powerStatus(CEC_POWER_STATUS_UNKNOWN),
e9de9629 53 m_processor(processor),
c4098482 54 m_vendor(CEC_VENDOR_UNKNOWN),
b64db02e 55 m_bReplaceHandler(false),
4abd6768 56 m_menuState(CEC_MENU_STATE_ACTIVATED),
8747dd4f 57 m_bActiveSource(false),
6a1c0009 58 m_iLastActive(0),
2efa39b7 59 m_iLastPowerStateUpdate(0),
f8ae3295 60 m_cecVersion(CEC_VERSION_UNKNOWN),
1344fd1a
LOK
61 m_deviceStatus(CEC_DEVICE_STATUS_UNKNOWN),
62 m_iHandlerUseCount(0),
63 m_bAwaitingReceiveFailed(false)
e9de9629
LOK
64{
65 m_handler = new CCECCommandHandler(this);
51b2a094 66
a3269a0a
LOK
67 for (unsigned int iPtr = 0; iPtr < 4; iPtr++)
68 m_menuLanguage.language[iPtr] = '?';
69 m_menuLanguage.language[3] = 0;
70 m_menuLanguage.device = iLogicalAddress;
1fcf5a3f 71
c4098482 72 m_strDeviceName = ToString(m_iLogicalAddress);
e9de9629
LOK
73}
74
75CCECBusDevice::~CCECBusDevice(void)
76{
77 delete m_handler;
78}
79
93729720 80bool CCECBusDevice::HandleCommand(const cec_command &command)
f8513317 81{
7f919115
LOK
82 bool bHandled(false);
83
84 /* update "last active" */
8fa35473 85 {
f00ff009 86 CLockObject lock(m_mutex);
8fa35473 87 m_iLastActive = GetTimeMs();
f4b7b1dc
LOK
88
89 if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
90 m_deviceStatus = CEC_DEVICE_STATUS_PRESENT;
1344fd1a
LOK
91
92 MarkBusy();
8fa35473
LOK
93 }
94
7f919115
LOK
95 /* handle the command */
96 bHandled = m_handler->HandleCommand(command);
8fa35473 97
7f919115
LOK
98 /* change status to present */
99 if (bHandled)
8d915412 100 {
f00ff009 101 CLockObject lock(m_mutex);
8fa35473 102 if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
8d915412 103 {
8fa35473 104 if (m_deviceStatus != CEC_DEVICE_STATUS_PRESENT)
5477a250 105 CLibCEC::AddLog(CEC_LOG_DEBUG, "device %s (%x) status changed to present after command %s", GetLogicalAddressName(), (uint8_t)GetLogicalAddress(), ToString(command.opcode));
8fa35473 106 m_deviceStatus = CEC_DEVICE_STATUS_PRESENT;
8d915412 107 }
8d915412 108 }
7f919115 109
1344fd1a 110 MarkReady();
7f919115 111 return bHandled;
93729720
LOK
112}
113
93729720
LOK
114bool CCECBusDevice::PowerOn(void)
115{
1344fd1a 116 bool bReturn(false);
f4698390 117 GetVendorId(); // ensure that we got the vendor id, because the implementations vary per vendor
c6d7f0e1 118
1344fd1a 119 MarkBusy();
8670c970
LOK
120 cec_power_status currentStatus = GetPowerStatus(false);
121 if (currentStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
122 currentStatus != CEC_POWER_STATUS_ON)
5e5637c6 123 {
8670c970
LOK
124 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
125 if (m_handler->PowerOn(GetMyLogicalAddress(), m_iLogicalAddress))
126 {
127 SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
128 bReturn = true;
129 }
130 }
131 else
132 {
133 CLibCEC::AddLog(CEC_LOG_NOTICE, "'%s' (%X) is already '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(currentStatus));
f437e4be
LOK
134 }
135
1344fd1a
LOK
136 MarkReady();
137 return bReturn;
93729720
LOK
138}
139
140bool CCECBusDevice::Standby(void)
141{
5477a250 142 CLibCEC::AddLog(CEC_LOG_DEBUG, "<< putting '%s' (%X) in standby mode", GetLogicalAddressName(), m_iLogicalAddress);
1344fd1a
LOK
143 MarkBusy();
144 bool bReturn = m_handler->TransmitStandby(GetMyLogicalAddress(), m_iLogicalAddress);
145 MarkReady();
146 return bReturn;
93729720
LOK
147}
148
149/** @name Getters */
150//@{
7f919115 151cec_version CCECBusDevice::GetCecVersion(bool bUpdate /* = false */)
93729720 152{
6bbfc3f7 153 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb
LOK
154 bool bRequestUpdate(false);
155 {
f00ff009 156 CLockObject lock(m_mutex);
ddb6ac5b 157 bRequestUpdate = bIsPresent &&
6bbfc3f7 158 (bUpdate || m_cecVersion == CEC_VERSION_UNKNOWN);
97fc4ffb
LOK
159 }
160
161 if (bRequestUpdate)
f294b22f 162 RequestCecVersion();
f294b22f 163
f00ff009 164 CLockObject lock(m_mutex);
f294b22f
LOK
165 return m_cecVersion;
166}
167
168bool CCECBusDevice::RequestCecVersion(void)
169{
170 bool bReturn(false);
b64db02e 171
66c3ef5a
LOK
172 if (!MyLogicalAddressContains(m_iLogicalAddress) &&
173 !IsUnsupportedFeature(CEC_OPCODE_GET_CEC_VERSION))
93729720 174 {
1344fd1a 175 MarkBusy();
5477a250 176 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting CEC version of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473
LOK
177
178 bReturn = m_handler->TransmitRequestCecVersion(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 179 MarkReady();
93729720 180 }
f294b22f 181 return bReturn;
93729720
LOK
182}
183
62f5527d
LOK
184const char* CCECBusDevice::GetLogicalAddressName(void) const
185{
c4098482 186 return ToString(m_iLogicalAddress);
62f5527d
LOK
187}
188
7f919115 189cec_menu_language &CCECBusDevice::GetMenuLanguage(bool bUpdate /* = false */)
93729720 190{
6bbfc3f7 191 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb
LOK
192 bool bRequestUpdate(false);
193 {
f00ff009 194 CLockObject lock(m_mutex);
ddb6ac5b 195 bRequestUpdate = (bIsPresent &&
97fc4ffb
LOK
196 (bUpdate || !strcmp(m_menuLanguage.language, "???")));
197 }
198
199 if (bRequestUpdate)
f294b22f 200 RequestMenuLanguage();
5e5637c6 201
f00ff009 202 CLockObject lock(m_mutex);
f294b22f
LOK
203 return m_menuLanguage;
204}
205
206bool CCECBusDevice::RequestMenuLanguage(void)
207{
208 bool bReturn(false);
b64db02e 209
4d738fe3
LOK
210 if (!MyLogicalAddressContains(m_iLogicalAddress) &&
211 !IsUnsupportedFeature(CEC_OPCODE_GET_MENU_LANGUAGE))
93729720 212 {
1344fd1a 213 MarkBusy();
5477a250 214 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting menu language of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473 215 bReturn = m_handler->TransmitRequestMenuLanguage(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 216 MarkReady();
93729720 217 }
f294b22f 218 return bReturn;
93729720
LOK
219}
220
3e61b350
LOK
221cec_menu_state CCECBusDevice::GetMenuState(void)
222{
f00ff009 223 CLockObject lock(m_mutex);
3e61b350
LOK
224 return m_menuState;
225}
226
93729720
LOK
227cec_logical_address CCECBusDevice::GetMyLogicalAddress(void) const
228{
229 return m_processor->GetLogicalAddress();
f8513317
LOK
230}
231
e9de9629
LOK
232uint16_t CCECBusDevice::GetMyPhysicalAddress(void) const
233{
234 return m_processor->GetPhysicalAddress();
235}
236
7f919115 237CStdString CCECBusDevice::GetOSDName(bool bUpdate /* = false */)
ed21be2a 238{
6bbfc3f7 239 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb
LOK
240 bool bRequestUpdate(false);
241 {
f00ff009 242 CLockObject lock(m_mutex);
ddb6ac5b 243 bRequestUpdate = bIsPresent &&
97fc4ffb 244 (bUpdate || m_strDeviceName.Equals(ToString(m_iLogicalAddress))) &&
ddb6ac5b 245 m_type != CEC_DEVICE_TYPE_TV;
97fc4ffb
LOK
246 }
247
248 if (bRequestUpdate)
5e5637c6
LOK
249 RequestOSDName();
250
f00ff009 251 CLockObject lock(m_mutex);
ed21be2a
LOK
252 return m_strDeviceName;
253}
254
255bool CCECBusDevice::RequestOSDName(void)
256{
257 bool bReturn(false);
b64db02e 258
4d738fe3
LOK
259 if (!MyLogicalAddressContains(m_iLogicalAddress) &&
260 !IsUnsupportedFeature(CEC_OPCODE_GIVE_OSD_NAME))
ed21be2a 261 {
1344fd1a 262 MarkBusy();
5477a250 263 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting OSD name of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473 264 bReturn = m_handler->TransmitRequestOSDName(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 265 MarkReady();
ed21be2a
LOK
266 }
267 return bReturn;
268}
269
7f919115 270uint16_t CCECBusDevice::GetPhysicalAddress(bool bUpdate /* = false */)
16b1e052 271{
6bbfc3f7 272 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb 273 bool bRequestUpdate(false);
16b1e052 274 {
f00ff009 275 CLockObject lock(m_mutex);
ddb6ac5b
LOK
276 bRequestUpdate = bIsPresent &&
277 (m_iPhysicalAddress == 0xFFFF || bUpdate);
16b1e052
LOK
278 }
279
97fc4ffb 280 if (bRequestUpdate && !RequestPhysicalAddress())
5477a250 281 CLibCEC::AddLog(CEC_LOG_ERROR, "failed to request the physical address");
97fc4ffb 282
f00ff009 283 CLockObject lock(m_mutex);
16b1e052
LOK
284 return m_iPhysicalAddress;
285}
286
287bool CCECBusDevice::RequestPhysicalAddress(void)
288{
289 bool bReturn(false);
b64db02e 290
16b1e052
LOK
291 if (!MyLogicalAddressContains(m_iLogicalAddress))
292 {
1344fd1a 293 MarkBusy();
5477a250 294 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting physical address of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473 295 bReturn = m_handler->TransmitRequestPhysicalAddress(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 296 MarkReady();
16b1e052
LOK
297 }
298 return bReturn;
299}
300
7f919115 301cec_power_status CCECBusDevice::GetPowerStatus(bool bUpdate /* = false */)
e9de9629 302{
6bbfc3f7 303 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb
LOK
304 bool bRequestUpdate(false);
305 {
f00ff009 306 CLockObject lock(m_mutex);
ddb6ac5b 307 bRequestUpdate = (bIsPresent &&
c8f0eef0 308 (bUpdate || m_powerStatus == CEC_POWER_STATUS_UNKNOWN ||
2efa39b7
LOK
309 m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON ||
310 m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY ||
311 GetTimeMs() - m_iLastPowerStateUpdate >= CEC_POWER_STATE_REFRESH_TIME));
97fc4ffb
LOK
312 }
313
314 if (bRequestUpdate)
f294b22f 315 RequestPowerStatus();
5e5637c6 316
f00ff009 317 CLockObject lock(m_mutex);
f294b22f
LOK
318 return m_powerStatus;
319}
320
321bool CCECBusDevice::RequestPowerStatus(void)
322{
323 bool bReturn(false);
b64db02e 324
4d738fe3
LOK
325 if (!MyLogicalAddressContains(m_iLogicalAddress) &&
326 !IsUnsupportedFeature(CEC_OPCODE_GIVE_DEVICE_POWER_STATUS))
93729720 327 {
1344fd1a 328 MarkBusy();
5477a250 329 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting power status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473 330 bReturn = m_handler->TransmitRequestPowerStatus(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 331 MarkReady();
93729720 332 }
f294b22f
LOK
333 return bReturn;
334}
93729720 335
7f919115 336cec_vendor_id CCECBusDevice::GetVendorId(bool bUpdate /* = false */)
f294b22f 337{
6bbfc3f7 338 bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
97fc4ffb
LOK
339 bool bRequestUpdate(false);
340 {
f00ff009 341 CLockObject lock(m_mutex);
ddb6ac5b 342 bRequestUpdate = (bIsPresent &&
97fc4ffb
LOK
343 (bUpdate || m_vendor == CEC_VENDOR_UNKNOWN));
344 }
345
346 if (bRequestUpdate)
f294b22f 347 RequestVendorId();
5e5637c6 348
f00ff009 349 CLockObject lock(m_mutex);
f294b22f 350 return m_vendor;
e9de9629
LOK
351}
352
f294b22f 353bool CCECBusDevice::RequestVendorId(void)
a3269a0a 354{
f294b22f 355 bool bReturn(false);
b64db02e 356
81a1e39d 357 if (!MyLogicalAddressContains(m_iLogicalAddress))
a3269a0a 358 {
1344fd1a 359 MarkBusy();
5477a250 360 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting vendor ID of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473 361 bReturn = m_handler->TransmitRequestVendorId(GetMyLogicalAddress(), m_iLogicalAddress);
1344fd1a 362 MarkReady();
3e61b350
LOK
363
364 ReplaceHandler(true);
a3269a0a 365 }
f294b22f 366 return bReturn;
93729720
LOK
367}
368
7f919115 369const char *CCECBusDevice::GetVendorName(bool bUpdate /* = false */)
c4098482 370{
7f919115 371 return ToString(GetVendorId(bUpdate));
c4098482
LOK
372}
373
93729720
LOK
374bool CCECBusDevice::MyLogicalAddressContains(cec_logical_address address) const
375{
376 return m_processor->HasLogicalAddress(address);
a3269a0a
LOK
377}
378
9fd73dd4
LOK
379bool CCECBusDevice::NeedsPoll(void)
380{
381 bool bSendPoll(false);
382 switch (m_iLogicalAddress)
383 {
384 case CECDEVICE_PLAYBACKDEVICE3:
c6d7f0e1
LOK
385 {
386 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_PLAYBACKDEVICE2]->GetStatus();
387 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
388 }
9fd73dd4
LOK
389 break;
390 case CECDEVICE_PLAYBACKDEVICE2:
c6d7f0e1
LOK
391 {
392 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_PLAYBACKDEVICE1]->GetStatus();
393 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
394 }
9fd73dd4
LOK
395 break;
396 case CECDEVICE_RECORDINGDEVICE3:
c6d7f0e1
LOK
397 {
398 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_RECORDINGDEVICE2]->GetStatus();
399 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
400 }
9fd73dd4
LOK
401 break;
402 case CECDEVICE_RECORDINGDEVICE2:
c6d7f0e1
LOK
403 {
404 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_RECORDINGDEVICE1]->GetStatus();
405 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
406 }
9fd73dd4
LOK
407 break;
408 case CECDEVICE_TUNER4:
c6d7f0e1
LOK
409 {
410 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_TUNER3]->GetStatus();
411 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
412 }
9fd73dd4
LOK
413 break;
414 case CECDEVICE_TUNER3:
c6d7f0e1
LOK
415 {
416 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_TUNER2]->GetStatus();
417 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
418 }
9fd73dd4
LOK
419 break;
420 case CECDEVICE_TUNER2:
c6d7f0e1
LOK
421 {
422 cec_bus_device_status status = m_processor->m_busDevices[CECDEVICE_TUNER1]->GetStatus();
423 bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
424 }
9fd73dd4
LOK
425 break;
426 case CECDEVICE_AUDIOSYSTEM:
427 case CECDEVICE_PLAYBACKDEVICE1:
428 case CECDEVICE_RECORDINGDEVICE1:
429 case CECDEVICE_TUNER1:
430 case CECDEVICE_TV:
431 bSendPoll = true;
432 break;
433 default:
434 break;
435 }
436
437 return bSendPoll;
438}
439
440cec_bus_device_status CCECBusDevice::GetStatus(bool bForcePoll /* = false */)
f8ae3295 441{
f00ff009 442 CLockObject lock(m_mutex);
b750a5c3
LOK
443 if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC &&
444 (m_deviceStatus == CEC_DEVICE_STATUS_UNKNOWN || bForcePoll))
f8ae3295 445 {
f00ff009 446 lock.Unlock();
9fd73dd4
LOK
447 bool bPollAcked(false);
448 if (bForcePoll || NeedsPoll())
449 bPollAcked = m_processor->PollDevice(m_iLogicalAddress);
95a73fa7
LOK
450
451 lock.Lock();
452 m_deviceStatus = bPollAcked ? CEC_DEVICE_STATUS_PRESENT : CEC_DEVICE_STATUS_NOT_PRESENT;
f8ae3295
LOK
453 }
454
455 return m_deviceStatus;
456}
457
93729720
LOK
458//@}
459
460/** @name Setters */
461//@{
e55f3f70 462void CCECBusDevice::SetCecVersion(const cec_version newVersion)
6a1c0009 463{
6a1c0009 464 m_cecVersion = newVersion;
5477a250 465 CLibCEC::AddLog(CEC_LOG_DEBUG, "%s (%X): CEC version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(newVersion));
6a1c0009
LOK
466}
467
93729720
LOK
468void CCECBusDevice::SetMenuLanguage(const cec_menu_language &language)
469{
f00ff009 470 CLockObject lock(m_mutex);
93729720
LOK
471 if (language.device == m_iLogicalAddress)
472 {
5477a250 473 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): menu language set to '%s'", GetLogicalAddressName(), m_iLogicalAddress, language.language);
93729720
LOK
474 m_menuLanguage = language;
475 }
476}
477
15d1a84c
LOK
478void CCECBusDevice::SetOSDName(CStdString strName)
479{
f00ff009 480 CLockObject lock(m_mutex);
15d1a84c
LOK
481 if (m_strDeviceName != strName)
482 {
5477a250 483 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): osd name set to '%s'", GetLogicalAddressName(), m_iLogicalAddress, strName.c_str());
15d1a84c
LOK
484 m_strDeviceName = strName;
485 }
486}
487
28fa6c97
LOK
488void CCECBusDevice::SetMenuState(const cec_menu_state state)
489{
f00ff009 490 CLockObject lock(m_mutex);
28fa6c97
LOK
491 if (m_menuState != state)
492 {
5477a250 493 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): menu state set to '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_menuState));
28fa6c97
LOK
494 m_menuState = state;
495 }
496}
497
3fd2a2b8 498void CCECBusDevice::SetInactiveSource(void)
7856411b 499{
3fd2a2b8 500 {
f00ff009 501 CLockObject lock(m_mutex);
3fd2a2b8
LOK
502 m_bActiveSource = false;
503 }
504
505 if (MyLogicalAddressContains(m_iLogicalAddress))
506 SetPowerStatus(CEC_POWER_STATUS_STANDBY);
7856411b
LOK
507}
508
37b0c572 509void CCECBusDevice::SetActiveSource(void)
7856411b 510{
f00ff009 511 CLockObject lock(m_mutex);
ff684fef 512 if (!m_bActiveSource)
5477a250 513 CLibCEC::AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
7856411b
LOK
514
515 for (int iPtr = 0; iPtr < 16; iPtr++)
516 if (iPtr != m_iLogicalAddress)
3fd2a2b8 517 m_processor->m_busDevices[iPtr]->SetInactiveSource();
7856411b
LOK
518
519 m_bActiveSource = true;
9a2f12df 520 SetPowerStatus(CEC_POWER_STATUS_ON);
7856411b
LOK
521}
522
93fff5c1
LOK
523bool CCECBusDevice::TryLogicalAddress(void)
524{
5477a250 525 CLibCEC::AddLog(CEC_LOG_DEBUG, "trying logical address '%s'", GetLogicalAddressName());
93fff5c1 526
b81f75db 527 m_processor->SetAckMask(0);
93fff5c1
LOK
528 if (!TransmitPoll(m_iLogicalAddress))
529 {
5477a250 530 CLibCEC::AddLog(CEC_LOG_NOTICE, "using logical address '%s'", GetLogicalAddressName());
93fff5c1
LOK
531 SetDeviceStatus(CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
532
533 return true;
534 }
535
5477a250 536 CLibCEC::AddLog(CEC_LOG_DEBUG, "logical address '%s' already taken", GetLogicalAddressName());
93fff5c1
LOK
537 SetDeviceStatus(CEC_DEVICE_STATUS_PRESENT);
538 return false;
539}
540
541void CCECBusDevice::SetDeviceStatus(const cec_bus_device_status newStatus)
542{
f00ff009 543 CLockObject lock(m_mutex);
93fff5c1
LOK
544 switch (newStatus)
545 {
546 case CEC_DEVICE_STATUS_UNKNOWN:
c4287bcd
LOK
547 if (m_deviceStatus != newStatus)
548 CLibCEC::AddLog(CEC_LOG_DEBUG, "device status of %s changed into 'unknown'", ToString(m_iLogicalAddress));
93fff5c1
LOK
549 m_iStreamPath = 0;
550 m_powerStatus = CEC_POWER_STATUS_UNKNOWN;
551 m_vendor = CEC_VENDOR_UNKNOWN;
552 m_menuState = CEC_MENU_STATE_ACTIVATED;
553 m_bActiveSource = false;
93fff5c1
LOK
554 m_iLastActive = 0;
555 m_cecVersion = CEC_VERSION_UNKNOWN;
556 m_deviceStatus = newStatus;
557 break;
558 case CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC:
c4287bcd
LOK
559 if (m_deviceStatus != newStatus)
560 CLibCEC::AddLog(CEC_LOG_DEBUG, "device status of %s changed into 'handled by libCEC'", ToString(m_iLogicalAddress));
93fff5c1 561 m_iStreamPath = 0;
9a2f12df 562 m_powerStatus = CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON;
93fff5c1
LOK
563 m_vendor = CEC_VENDOR_UNKNOWN;
564 m_menuState = CEC_MENU_STATE_ACTIVATED;
565 m_bActiveSource = false;
93fff5c1
LOK
566 m_iLastActive = 0;
567 m_cecVersion = CEC_VERSION_1_3A;
568 m_deviceStatus = newStatus;
569 break;
570 case CEC_DEVICE_STATUS_PRESENT:
c4287bcd
LOK
571 if (m_deviceStatus != newStatus)
572 CLibCEC::AddLog(CEC_LOG_DEBUG, "device status of %s changed into 'present'", ToString(m_iLogicalAddress));
573 m_deviceStatus = newStatus;
574 break;
93fff5c1 575 case CEC_DEVICE_STATUS_NOT_PRESENT:
c4287bcd
LOK
576 if (m_deviceStatus != newStatus)
577 CLibCEC::AddLog(CEC_LOG_DEBUG, "device status of %s changed into 'not present'", ToString(m_iLogicalAddress));
93fff5c1
LOK
578 m_deviceStatus = newStatus;
579 break;
580 }
581}
582
9dc04b07 583void CCECBusDevice::SetPhysicalAddress(uint16_t iNewAddress)
93729720 584{
f00ff009 585 CLockObject lock(m_mutex);
b8176e3c 586 if (iNewAddress > 0 && m_iPhysicalAddress != iNewAddress)
93729720 587 {
5477a250 588 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): physical address changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress, iNewAddress);
93729720
LOK
589 m_iPhysicalAddress = iNewAddress;
590 }
591}
592
9dc04b07
LOK
593void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = 0 */)
594{
f00ff009 595 CLockObject lock(m_mutex);
9dc04b07
LOK
596 if (iNewAddress > 0)
597 {
5477a250 598 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): stream path changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, iOldAddress == 0 ? m_iStreamPath : iOldAddress, iNewAddress);
9dc04b07 599 m_iStreamPath = iNewAddress;
96274140
LOK
600
601 if (iNewAddress > 0)
81a1e39d 602 {
f00ff009 603 lock.Unlock();
96274140 604 SetPowerStatus(CEC_POWER_STATUS_ON);
81a1e39d 605 }
9dc04b07
LOK
606 }
607}
608
e55f3f70
LOK
609void CCECBusDevice::SetPowerStatus(const cec_power_status powerStatus)
610{
f00ff009 611 CLockObject lock(m_mutex);
b0271d54
LOK
612 if (m_powerStatus != powerStatus)
613 {
2efa39b7 614 m_iLastPowerStateUpdate = GetTimeMs();
5477a250 615 CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): power status changed from '%s' to '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_powerStatus), ToString(powerStatus));
b0271d54
LOK
616 m_powerStatus = powerStatus;
617 }
e55f3f70
LOK
618}
619
1344fd1a
LOK
620void CCECBusDevice::MarkBusy(void)
621{
622 CLockObject handlerLock(m_handlerMutex);
623 ++m_iHandlerUseCount;
624}
625
626void CCECBusDevice::MarkReady(void)
627{
628 CLockObject handlerLock(m_handlerMutex);
629 if (m_iHandlerUseCount > 0)
630 --m_iHandlerUseCount;
631}
632
3e61b350 633bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
e9de9629 634{
94e9a2af
LOK
635 bool bInitHandler(false);
636 {
637 CTryLockObject lock(m_mutex);
638 if (!lock.IsLocked())
639 return false;
2563e7eb 640
94e9a2af
LOK
641 CLockObject handlerLock(m_handlerMutex);
642 if (m_iHandlerUseCount > 0)
643 return false;
d211708b 644
94e9a2af 645 MarkBusy();
104125dc 646
94e9a2af 647 if (m_vendor != m_handler->GetVendorId())
3e61b350 648 {
94e9a2af 649 if (CCECCommandHandler::HasSpecificHandler(m_vendor))
2e49a6e4 650 {
94e9a2af
LOK
651 CLibCEC::AddLog(CEC_LOG_DEBUG, "replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
652 delete m_handler;
653
654 switch (m_vendor)
655 {
656 case CEC_VENDOR_SAMSUNG:
657 m_handler = new CANCommandHandler(this);
658 break;
659 case CEC_VENDOR_LG:
660 m_handler = new CSLCommandHandler(this);
661 break;
662 case CEC_VENDOR_PANASONIC:
663 m_handler = new CVLCommandHandler(this);
664 break;
665 default:
666 m_handler = new CCECCommandHandler(this);
667 break;
668 }
669
670 m_handler->SetVendorId(m_vendor);
671 bInitHandler = true;
2e49a6e4 672 }
2e49a6e4 673 }
e9de9629
LOK
674 }
675
104125dc
LOK
676 if (bInitHandler)
677 {
678 m_handler->InitHandler();
679
680 if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised() && IsActiveSource())
681 m_handler->ActivateSource();
682 }
683
684 MarkReady();
685
b64db02e
LOK
686 return true;
687}
688
3e61b350 689bool CCECBusDevice::SetVendorId(uint64_t iVendorId)
b64db02e
LOK
690{
691 bool bVendorChanged(false);
692
693 {
f00ff009 694 CLockObject lock(m_mutex);
b64db02e
LOK
695 bVendorChanged = (m_vendor != (cec_vendor_id)iVendorId);
696 m_vendor = (cec_vendor_id)iVendorId;
b64db02e 697 }
8d915412 698
5477a250 699 CLibCEC::AddLog(CEC_LOG_DEBUG, "%s (%X): vendor = %s (%06x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_vendor), m_vendor);
8fa35473
LOK
700
701 return bVendorChanged;
e9de9629 702}
93729720 703//@}
e9de9629 704
93729720
LOK
705/** @name Transmit methods */
706//@{
707bool CCECBusDevice::TransmitActiveSource(void)
0f23c85c 708{
8fa35473 709 bool bSendActiveSource(false);
0f23c85c 710
8747dd4f 711 {
f00ff009 712 CLockObject lock(m_mutex);
49c8f2e4 713 if (m_powerStatus != CEC_POWER_STATUS_ON && m_powerStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON)
5477a250 714 CLibCEC::AddLog(CEC_LOG_DEBUG, "<< %s (%X) is not powered on", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473
LOK
715 else if (m_bActiveSource)
716 {
5477a250 717 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): active source (%4x)", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
8fa35473
LOK
718 bSendActiveSource = true;
719 }
720 else
5477a250 721 CLibCEC::AddLog(CEC_LOG_DEBUG, "<< %s (%X) is not the active source", GetLogicalAddressName(), m_iLogicalAddress);
8747dd4f
LOK
722 }
723
b64db02e
LOK
724 if (bSendActiveSource)
725 {
1344fd1a 726 MarkBusy();
468a1414 727 m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress);
1344fd1a 728 MarkReady();
b64db02e
LOK
729 return true;
730 }
731
732 return false;
0f23c85c
LOK
733}
734
29912296 735bool CCECBusDevice::TransmitCECVersion(cec_logical_address dest)
0f23c85c 736{
8fa35473
LOK
737 cec_version version;
738 {
f00ff009 739 CLockObject lock(m_mutex);
5477a250 740 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): cec version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_cecVersion));
8fa35473
LOK
741 version = m_cecVersion;
742 }
0f23c85c 743
1344fd1a
LOK
744 MarkBusy();
745 bool bReturn = m_handler->TransmitCECVersion(m_iLogicalAddress, dest, version);
746 MarkReady();
747 return bReturn;
0f23c85c
LOK
748}
749
49c8f2e4
LOK
750bool CCECBusDevice::TransmitImageViewOn(void)
751{
49c8f2e4 752 {
9a2f12df
LOK
753 CLockObject lock(m_mutex);
754 if (m_powerStatus != CEC_POWER_STATUS_ON && m_powerStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON)
755 {
756 CLibCEC::AddLog(CEC_LOG_DEBUG, "<< %s (%X) is not powered on", GetLogicalAddressName(), m_iLogicalAddress);
757 return false;
758 }
49c8f2e4 759 }
9a2f12df
LOK
760
761 MarkBusy();
762 m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV);
763 MarkReady();
764 return true;
49c8f2e4
LOK
765}
766
ab27363d 767bool CCECBusDevice::TransmitInactiveSource(void)
93729720 768{
8fa35473
LOK
769 uint16_t iPhysicalAddress;
770 {
f00ff009 771 CLockObject lock(m_mutex);
5477a250 772 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): inactive source", GetLogicalAddressName(), m_iLogicalAddress);
8fa35473
LOK
773 iPhysicalAddress = m_iPhysicalAddress;
774 }
93729720 775
1344fd1a
LOK
776 MarkBusy();
777 bool bReturn = m_handler->TransmitInactiveSource(m_iLogicalAddress, iPhysicalAddress);
778 MarkReady();
779 return bReturn;
93729720
LOK
780}
781
29912296 782bool CCECBusDevice::TransmitMenuState(cec_logical_address dest)
0f23c85c 783{
8fa35473
LOK
784 cec_menu_state menuState;
785 {
f00ff009 786 CLockObject lock(m_mutex);
5477a250 787 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): menu state '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_menuState));
8fa35473
LOK
788 menuState = m_menuState;
789 }
0f23c85c 790
1344fd1a
LOK
791 MarkBusy();
792 bool bReturn = m_handler->TransmitMenuState(m_iLogicalAddress, dest, menuState);
793 MarkReady();
794 return bReturn;
0f23c85c
LOK
795}
796
29912296 797bool CCECBusDevice::TransmitOSDName(cec_logical_address dest)
0f23c85c 798{
8fa35473
LOK
799 CStdString strDeviceName;
800 {
f00ff009 801 CLockObject lock(m_mutex);
5477a250 802 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): OSD name '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, m_strDeviceName.c_str());
8fa35473
LOK
803 strDeviceName = m_strDeviceName;
804 }
0f23c85c 805
1344fd1a
LOK
806 MarkBusy();
807 bool bReturn = m_handler->TransmitOSDName(m_iLogicalAddress, dest, strDeviceName);
808 MarkReady();
809 return bReturn;
0f23c85c
LOK
810}
811
38bdb943
LOK
812bool CCECBusDevice::TransmitOSDString(cec_logical_address dest, cec_display_control duration, const char *strMessage)
813{
1344fd1a 814 bool bReturn(false);
66c3ef5a 815 if (!m_processor->m_busDevices[dest]->IsUnsupportedFeature(CEC_OPCODE_SET_OSD_STRING))
4d738fe3 816 {
5477a250 817 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, strMessage);
1344fd1a
LOK
818 MarkBusy();
819 bReturn = m_handler->TransmitOSDString(m_iLogicalAddress, dest, duration, strMessage);
820 MarkReady();
4d738fe3 821 }
1344fd1a 822 return bReturn;
38bdb943
LOK
823}
824
29912296 825bool CCECBusDevice::TransmitPhysicalAddress(void)
0f23c85c 826{
8fa35473
LOK
827 uint16_t iPhysicalAddress;
828 cec_device_type type;
829 {
f00ff009 830 CLockObject lock(m_mutex);
8fa35473
LOK
831 if (m_iPhysicalAddress == 0xffff)
832 return false;
2bdfdeef 833
5477a250 834 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): physical adddress %4x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
8fa35473
LOK
835 iPhysicalAddress = m_iPhysicalAddress;
836 type = m_type;
837 }
0f23c85c 838
1344fd1a
LOK
839 MarkBusy();
840 bool bReturn = m_handler->TransmitPhysicalAddress(m_iLogicalAddress, iPhysicalAddress, type);
841 MarkReady();
842 return bReturn;
0f23c85c
LOK
843}
844
93729720 845bool CCECBusDevice::TransmitPoll(cec_logical_address dest)
57f45e6c
LOK
846{
847 bool bReturn(false);
93729720
LOK
848 if (dest == CECDEVICE_UNKNOWN)
849 dest = m_iLogicalAddress;
f8513317 850
b750a5c3
LOK
851 CCECBusDevice *destDevice = m_processor->m_busDevices[dest];
852 if (destDevice->m_deviceStatus == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
853 return bReturn;
854
1344fd1a 855 MarkBusy();
5477a250 856 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
8fa35473 857 bReturn = m_handler->TransmitPoll(m_iLogicalAddress, dest);
5477a250 858 CLibCEC::AddLog(CEC_LOG_DEBUG, bReturn ? ">> POLL sent" : ">> POLL not sent");
8fa35473 859
f00ff009 860 CLockObject lock(m_mutex);
1674de37 861 if (bReturn)
8fa35473 862 {
1674de37 863 m_iLastActive = GetTimeMs();
b750a5c3 864 destDevice->m_deviceStatus = CEC_DEVICE_STATUS_PRESENT;
8fa35473 865 }
b750a5c3
LOK
866 else
867 destDevice->m_deviceStatus = CEC_DEVICE_STATUS_NOT_PRESENT;
1674de37 868
1344fd1a 869 MarkReady();
57f45e6c
LOK
870 return bReturn;
871}
93729720
LOK
872
873bool CCECBusDevice::TransmitPowerState(cec_logical_address dest)
874{
8fa35473
LOK
875 cec_power_status state;
876 {
f00ff009 877 CLockObject lock(m_mutex);
bbc71623
LOK
878 if (!IsActiveSource())
879 SetPowerStatus(CEC_POWER_STATUS_STANDBY);
880
5477a250 881 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_powerStatus));
8fa35473
LOK
882 state = m_powerStatus;
883 }
93729720 884
1344fd1a
LOK
885 MarkBusy();
886 bool bReturn = m_handler->TransmitPowerState(m_iLogicalAddress, dest, state);
887 MarkReady();
888 return bReturn;
93729720
LOK
889}
890
fe6f8e37 891bool CCECBusDevice::TransmitVendorID(cec_logical_address dest, bool bSendAbort /* = true */)
93729720 892{
1344fd1a 893 bool bReturn(false);
8fa35473
LOK
894 uint64_t iVendorId;
895 {
f00ff009 896 CLockObject lock(m_mutex);
8fa35473
LOK
897 iVendorId = (uint64_t)m_vendor;
898 }
899
1344fd1a 900 MarkBusy();
8fa35473 901 if (iVendorId == CEC_VENDOR_UNKNOWN)
c4098482 902 {
fe6f8e37
LOK
903 if (bSendAbort)
904 {
5477a250 905 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): vendor id feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
fe6f8e37 906 m_processor->TransmitAbort(dest, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
1344fd1a 907 bReturn = true;
fe6f8e37 908 }
c4098482
LOK
909 }
910 else
911 {
5477a250 912 CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString((cec_vendor_id)iVendorId), iVendorId);
1344fd1a 913 bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, iVendorId);
c4098482 914 }
1344fd1a
LOK
915 MarkReady();
916 return bReturn;
93729720 917}
a33794d8 918
4bec9d79 919bool CCECBusDevice::TransmitKeypress(cec_user_control_code key, bool bWait /* = true */)
a33794d8 920{
1344fd1a
LOK
921 MarkBusy();
922 bool bReturn = m_handler->TransmitKeypress(m_processor->GetLogicalAddress(), m_iLogicalAddress, key, bWait);
923 MarkReady();
924 return bReturn;
a33794d8
LOK
925}
926
4bec9d79 927bool CCECBusDevice::TransmitKeyRelease(bool bWait /* = true */)
a33794d8 928{
1344fd1a
LOK
929 MarkBusy();
930 bool bReturn = m_handler->TransmitKeyRelease(m_processor->GetLogicalAddress(), m_iLogicalAddress, bWait);
931 MarkReady();
932 return bReturn;
a33794d8 933}
4d738fe3
LOK
934
935bool CCECBusDevice::IsUnsupportedFeature(cec_opcode opcode) const
936{
66c3ef5a
LOK
937 bool bUnsupported = (m_unsupportedFeatures.find(opcode) != m_unsupportedFeatures.end());
938 if (bUnsupported)
939 CLibCEC::AddLog(CEC_LOG_NOTICE, "'%s' is marked as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
940 return bUnsupported;
4d738fe3
LOK
941}
942
943void CCECBusDevice::SetUnsupportedFeature(cec_opcode opcode)
944{
66c3ef5a 945 CLibCEC::AddLog(CEC_LOG_DEBUG, "marking opcode '%s' as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
4d738fe3
LOK
946 m_unsupportedFeatures.insert(opcode);
947}
b64db02e 948
3e61b350 949bool CCECBusDevice::ActivateSource(void)
b64db02e 950{
1344fd1a
LOK
951 MarkBusy();
952 bool bReturn = m_handler->ActivateSource();
953 MarkReady();
954 return bReturn;
b64db02e
LOK
955}
956
ef583662 957void CCECBusDevice::HandlePoll(cec_logical_address iDestination)
0cfdeb5a 958{
ef583662
LOK
959 CLibCEC::AddLog(CEC_LOG_DEBUG, "<< POLL: %s (%x) -> %s (%x)", ToString(m_iLogicalAddress), m_iLogicalAddress, ToString(iDestination), iDestination);
960 m_bAwaitingReceiveFailed = true;
0cfdeb5a
LOK
961}
962
963bool CCECBusDevice::HandleReceiveFailed(void)
964{
ef583662
LOK
965 bool bReturn = m_bAwaitingReceiveFailed;
966 m_bAwaitingReceiveFailed = false;
967 return bReturn;
0cfdeb5a
LOK
968}
969
93729720 970//@}