#include "CECBusDevice.h"
#include "../CECProcessor.h"
+#include "../CECClient.h"
#include "../implementations/ANCommandHandler.h"
#include "../implementations/CECCommandHandler.h"
#include "../implementations/SLCommandHandler.h"
m_deviceStatus (CEC_DEVICE_STATUS_UNKNOWN),
m_iHandlerUseCount (0),
m_bAwaitingReceiveFailed(false),
- m_bVendorIdRequested (false)
+ m_bVendorIdRequested (false),
+ m_waitForResponse (new CWaitForResponse)
{
m_handler = new CCECCommandHandler(this);
CCECBusDevice::~CCECBusDevice(void)
{
DELETE_AND_NULL(m_handler);
+ DELETE_AND_NULL(m_waitForResponse);
}
bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
if (CCECCommandHandler::HasSpecificHandler(m_vendor))
{
LIB_CEC->AddLog(CEC_LOG_DEBUG, "replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
+
+ int32_t iTransmitTimeout = m_handler->m_iTransmitTimeout;
+ int32_t iTransmitWait = m_handler->m_iTransmitWait;
+ int8_t iTransmitRetries = m_handler->m_iTransmitRetries;
+ int64_t iActiveSourcePending = m_handler->m_iActiveSourcePending;
+
DELETE_AND_NULL(m_handler);
switch (m_vendor)
{
case CEC_VENDOR_SAMSUNG:
- m_handler = new CANCommandHandler(this);
+ m_handler = new CANCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
break;
case CEC_VENDOR_LG:
- m_handler = new CSLCommandHandler(this);
+ m_handler = new CSLCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
break;
case CEC_VENDOR_PANASONIC:
- m_handler = new CVLCommandHandler(this);
+ m_handler = new CVLCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
break;
default:
- m_handler = new CCECCommandHandler(this);
+ m_handler = new CCECCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
break;
}
// signal threads that are waiting for a reponse
MarkBusy();
- m_handler->SignalOpcode(cec_command::GetResponseOpcode(opcode));
+ SignalOpcode(cec_command::GetResponseOpcode(opcode));
MarkReady();
}
m_iLastActive = 0;
m_bVendorIdRequested = false;
m_unsupportedFeatures.clear();
+ m_waitForResponse->Clear();
if (m_deviceStatus != CEC_DEVICE_STATUS_UNKNOWN)
LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X): device status changed into 'unknown'", GetLogicalAddressName(), m_iLogicalAddress);
return bReturn;
}
-bool CCECBusDevice::ActivateSource(void)
+bool CCECBusDevice::ActivateSource(uint64_t iDelay /* = 0 */)
{
MarkAsActiveSource();
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "activating source '%s'", ToString(m_iLogicalAddress));
MarkBusy();
- bool bReturn = m_handler->ActivateSource();
+ bool bReturn(true);
+ if (iDelay == 0)
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending active source message for '%s'", ToString(m_iLogicalAddress));
+ bReturn = m_handler->ActivateSource();
+ }
+ else
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "scheduling active source message for '%s'", ToString(m_iLogicalAddress));
+ m_handler->ScheduleActivateSource(iDelay);
+ }
MarkReady();
return bReturn;
}
void CCECBusDevice::MarkAsActiveSource(void)
{
- CLockObject lock(m_mutex);
- if (!m_bActiveSource)
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
- else
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress);
+ bool bWasActivated(false);
+
+ // set the power status to powered on
+ SetPowerStatus(CEC_POWER_STATUS_ON);
+
+ // mark this device as active source
+ {
+ CLockObject lock(m_mutex);
+ if (!m_bActiveSource)
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
+ bWasActivated = true;
+ }
+ else
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress);
+ m_bActiveSource = true;
+ }
+
+ // mark other devices as inactive sources
CECDEVICEVEC devices;
m_processor->GetDevices()->Get(devices);
for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++)
if ((*it)->GetLogicalAddress() != m_iLogicalAddress)
(*it)->MarkAsInactiveSource();
- m_bActiveSource = true;
- SetPowerStatus(CEC_POWER_STATUS_ON);
+ if (bWasActivated)
+ {
+ CCECClient *client = GetClient();
+ if (client)
+ client->SourceActivated(m_iLogicalAddress);
+ }
}
void CCECBusDevice::MarkAsInactiveSource(void)
{
+ bool bWasDeactivated(false);
{
CLockObject lock(m_mutex);
if (m_bActiveSource)
+ {
LIB_CEC->AddLog(CEC_LOG_DEBUG, "marking %s (%X) as inactive source", GetLogicalAddressName(), m_iLogicalAddress);
+ bWasDeactivated = true;
+ }
m_bActiveSource = false;
}
+
+ if (bWasDeactivated)
+ {
+ CCECClient *client = GetClient();
+ if (client)
+ client->SourceDeactivated(m_iLogicalAddress);
+ }
}
bool CCECBusDevice::TransmitActiveSource(void)
CLockObject lock(m_mutex);
if (!HasValidPhysicalAddress())
{
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X) has an invalid physical address, not sending active source commands", GetLogicalAddressName(), m_iLogicalAddress);
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X) has an invalid physical address (%04x), not sending active source commands", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
return false;
}
{
return m_processor->GetClient(m_iLogicalAddress);
}
+
+void CCECBusDevice::SignalOpcode(cec_opcode opcode)
+{
+ m_waitForResponse->Received(opcode);
+}
+
+bool CCECBusDevice::WaitForOpcode(cec_opcode opcode)
+{
+ return m_waitForResponse->Wait(opcode);
+}