X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fdevices%2FCECBusDevice.cpp;h=91dd83538c90ee213310c22c93ed648548ea1861;hb=ebefc26c10d68ba9ced2a30c896dccc81c6c2eeb;hp=47bd53aff566b60bcf98ece20a76867a1539805a;hpb=aa4c0d341117a7e3b75b665fbc61f3bb40be5d79;p=deb_libcec.git diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index 47bd53a..91dd835 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -32,6 +32,7 @@ #include "CECBusDevice.h" #include "../CECProcessor.h" +#include "../CECClient.h" #include "../implementations/ANCommandHandler.h" #include "../implementations/CECCommandHandler.h" #include "../implementations/SLCommandHandler.h" @@ -71,7 +72,8 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi 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); @@ -86,6 +88,7 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi CCECBusDevice::~CCECBusDevice(void) { DELETE_AND_NULL(m_handler); + DELETE_AND_NULL(m_waitForResponse); } bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */) @@ -107,21 +110,27 @@ 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; } @@ -230,7 +239,7 @@ void CCECBusDevice::SetUnsupportedFeature(cec_opcode opcode) // signal threads that are waiting for a reponse MarkBusy(); - m_handler->SignalOpcode(cec_command::GetResponseOpcode(opcode)); + SignalOpcode(cec_command::GetResponseOpcode(opcode)); MarkReady(); } @@ -800,6 +809,7 @@ void CCECBusDevice::ResetDeviceStatus(void) 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); @@ -889,12 +899,21 @@ bool CCECBusDevice::TransmitMenuState(const cec_logical_address dest) 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; } @@ -916,30 +935,59 @@ bool CCECBusDevice::RequestActiveSource(bool bWaitForResponse /* = true */) 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) @@ -951,7 +999,7 @@ 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; } @@ -1252,3 +1300,13 @@ CCECClient *CCECBusDevice::GetClient(void) { 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); +}