From 468a141464d9b9a088df8abd35f5ebb138424155 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Thu, 29 Dec 2011 01:37:14 +0100 Subject: [PATCH] cec: clean up and fix the LG command handler --- src/lib/devices/CECBusDevice.cpp | 2 +- src/lib/implementations/CECCommandHandler.cpp | 3 + src/lib/implementations/CECCommandHandler.h | 1 + src/lib/implementations/SLCommandHandler.cpp | 227 ++++++++---------- src/lib/implementations/SLCommandHandler.h | 20 +- 5 files changed, 112 insertions(+), 141 deletions(-) diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index 328e2b6..c2704ae 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -684,8 +684,8 @@ bool CCECBusDevice::TransmitActiveSource(void) if (bSendActiveSource) { - m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress); m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV); + m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress); return true; } diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 0fac17f..c72155c 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -166,6 +166,9 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) case CEC_OPCODE_FEATURE_ABORT: HandleFeatureAbort(command); break; + case CEC_OPCODE_VENDOR_COMMAND: + HandleVendorCommand(command); + break; default: UnhandledCommand(command); bHandled = false; diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index 9ced829..c84424f 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -117,6 +117,7 @@ namespace CEC virtual bool HandleTextViewOn(const cec_command &command); virtual bool HandleUserControlPressed(const cec_command &command); virtual bool HandleUserControlRelease(const cec_command &command); + virtual bool HandleVendorCommand(const cec_command &command) { return true; } virtual void UnhandledCommand(const cec_command &command); virtual unsigned int GetMyDevices(std::vector &devices) const; diff --git a/src/lib/implementations/SLCommandHandler.cpp b/src/lib/implementations/SLCommandHandler.cpp index 154452d..bc302aa 100644 --- a/src/lib/implementations/SLCommandHandler.cpp +++ b/src/lib/implementations/SLCommandHandler.cpp @@ -35,6 +35,7 @@ #include "../devices/CECPlaybackDevice.h" #include "../CECProcessor.h" #include "../platform/timeutils.h" +#include "../platform/threads.h" using namespace CEC; @@ -51,13 +52,14 @@ CSLCommandHandler::CSLCommandHandler(CCECBusDevice *busDevice) : CCECCommandHandler(busDevice), m_bAwaitingReceiveFailed(false), m_bSLEnabled(false), - m_bVendorIdSent(false) + m_bPowerStateReset(false) { CCECBusDevice *primary = m_processor->GetPrimaryDevice(); /* imitate LG devices */ if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress()) primary->SetVendorId(CEC_VENDOR_LG, false); + SetLGDeckStatus(); /* LG TVs don't always reply to CEC version requests, so just set it to 1.3a */ if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV) @@ -70,16 +72,74 @@ CSLCommandHandler::CSLCommandHandler(CCECBusDevice *busDevice) : m_busDevice->SetMenuLanguage(lang); } -void CSLCommandHandler::SetLGDeckStatus(void) + +void CSLCommandHandler::HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination) { - /* LG TVs only route keypresses when the deck status is set to 0x20 */ - CCECBusDevice *device = m_processor->GetDeviceByType(CEC_DEVICE_TYPE_PLAYBACK_DEVICE); - if (device) - ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG); + CCECCommandHandler::HandlePoll(iInitiator, iDestination); + m_bAwaitingReceiveFailed = true; +} - device = m_processor->GetDeviceByType(CEC_DEVICE_TYPE_RECORDING_DEVICE); - if (device) - ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG); +bool CSLCommandHandler::HandleReceiveFailed(void) +{ + if (m_bAwaitingReceiveFailed) + { + m_bAwaitingReceiveFailed = false; + return false; + } + + return true; +} + +bool CSLCommandHandler::InitHandler(void) +{ + if (m_bHandlerInited) + return true; + m_bHandlerInited = true; + + /* reply with LGs vendor id */ + CCECBusDevice *primary = m_processor->GetPrimaryDevice(); + if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress()) + primary->TransmitVendorID(CECDEVICE_TV, false); + + primary->SetPowerStatus(CEC_POWER_STATUS_STANDBY); + return true; +} + +bool CSLCommandHandler::HandleActiveSource(const cec_command &command) +{ + if (command.parameters.size == 2) + { + uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]); + if (iAddress != m_busDevice->GetPhysicalAddress(false)) + m_bSLEnabled = false; + return m_processor->SetActiveSource(iAddress); + } + + return true; +} + +bool CSLCommandHandler::HandleFeatureAbort(const cec_command &command) +{ + CCECBusDevice *primary = m_processor->GetPrimaryDevice(); + if (primary->GetPowerStatus(false) == CEC_POWER_STATUS_ON && !m_bPowerStateReset && !m_bSLEnabled) + { + m_bPowerStateReset = true; + primary->SetPowerStatus(CEC_POWER_STATUS_STANDBY); + } + + return CCECCommandHandler::HandleFeatureAbort(command); +} + +bool CSLCommandHandler::HandleGivePhysicalAddress(const cec_command &command) +{ + if (m_processor->IsStarted() && m_busDevice->MyLogicalAddressContains(command.destination)) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitPhysicalAddress(); + } + + return false; } bool CSLCommandHandler::HandleVendorCommand(const cec_command &command) @@ -127,39 +187,22 @@ void CSLCommandHandler::TransmitVendorCommand0205(const cec_logical_address iSou Transmit(response, false); } -void CSLCommandHandler::TransmitVendorCommand05(const cec_logical_address iSource, const cec_logical_address iDestination) -{ - m_bSLEnabled = true; - cec_command response; - cec_command::Format(response, iSource, iDestination, CEC_OPCODE_VENDOR_COMMAND); - response.PushBack(SL_COMMAND_CONNECT_ACCEPT); - response.PushBack((uint8_t)iSource); - Transmit(response, false); -} - void CSLCommandHandler::HandleVendorCommandPowerOn(const cec_command &command) { CCECBusDevice *device = m_processor->GetPrimaryDevice(); if (device) { m_bSLEnabled = true; - SetLGDeckStatus(); - device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); + + device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); //XXX device->TransmitPowerState(command.initiator); - device->TransmitVendorID(command.initiator); - TransmitPowerOn(device->GetLogicalAddress(), command.initiator); - } -} + device->SetPowerStatus(CEC_POWER_STATUS_ON); -void CSLCommandHandler::HandleVendorCommandSLConnect(const cec_command &command) -{ - m_bSLEnabled = true; - m_processor->m_busDevices[command.initiator]->SetActiveSource(); - m_processor->m_busDevices[command.destination]->TransmitActiveSource(); - TransmitVendorCommand05(command.destination, command.initiator); - SetLGDeckStatus(); + SetLGDeckStatus(); + device->SetActiveSource(); + TransmitImageViewOn(device->GetLogicalAddress(), command.initiator); + } } - void CSLCommandHandler::HandleVendorCommandPowerOnStatus(const cec_command &command) { if (command.destination != CECDEVICE_BROADCAST) @@ -171,113 +214,35 @@ void CSLCommandHandler::HandleVendorCommandPowerOnStatus(const cec_command &comm } } -bool CSLCommandHandler::TransmitLGVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination) -{ - cec_command response; - cec_command::Format(response, iInitiator, iDestination, CEC_OPCODE_DEVICE_VENDOR_ID); - response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 16) & 0xFF)); - response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 8) & 0xFF)); - response.parameters.PushBack((uint8_t) ((uint64_t)CEC_VENDOR_LG & 0xFF)); - - Transmit(response, false); - - cec_command::Format(response, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); - Transmit(response); - - return true; -} - -bool CSLCommandHandler::HandleCommand(const cec_command &command) -{ - bool bHandled(false); - - if (m_processor->IsStarted() && (m_busDevice->MyLogicalAddressContains(command.destination) || - command.destination == CECDEVICE_BROADCAST)) - { - switch(command.opcode) - { - case CEC_OPCODE_VENDOR_COMMAND: - bHandled = HandleVendorCommand(command); - break; - case CEC_OPCODE_FEATURE_ABORT: - { - if (!m_bVendorIdSent) - { - m_bVendorIdSent = true; - TransmitLGVendorId(m_processor->GetLogicalAddresses().primary, CECDEVICE_BROADCAST); - m_processor->GetPrimaryDevice()->SetPowerStatus(CEC_POWER_STATUS_STANDBY); - } - } - bHandled = true; - break; - default: - break; - } - } - - if (!bHandled) - bHandled = CCECCommandHandler::HandleCommand(command); - - return bHandled; -} - -void CSLCommandHandler::HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination) -{ - CCECCommandHandler::HandlePoll(iInitiator, iDestination); - m_bAwaitingReceiveFailed = true; -} - -bool CSLCommandHandler::HandleReceiveFailed(void) -{ - if (m_bAwaitingReceiveFailed) - { - m_bAwaitingReceiveFailed = false; - return false; - } - - return true; -} - -bool CSLCommandHandler::InitHandler(void) +void CSLCommandHandler::HandleVendorCommandSLConnect(const cec_command &command) { - if (m_bHandlerInited) - return true; - m_bHandlerInited = true; + m_bSLEnabled = true; + SetLGDeckStatus(); - /* reply with LGs vendor id */ CCECBusDevice *primary = m_processor->GetPrimaryDevice(); - if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress()) - primary->TransmitVendorID(CECDEVICE_TV, false); - return true; + primary->SetActiveSource(); + TransmitImageViewOn(primary->GetLogicalAddress(), command.initiator); + TransmitVendorCommand05(primary->GetLogicalAddress(), command.initiator); } -bool CSLCommandHandler::TransmitPowerOn(const cec_logical_address iInitiator, const cec_logical_address iDestination) +void CSLCommandHandler::TransmitVendorCommand05(const cec_logical_address iSource, const cec_logical_address iDestination) { - if (iDestination != CECDEVICE_BROADCAST && - iDestination != CECDEVICE_TV && - m_processor->m_busDevices[iDestination]->GetVendorId(false) == CEC_VENDOR_LG) - { - cec_command command; - cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_VENDOR_COMMAND); - command.parameters.PushBack((uint8_t)SL_COMMAND_POWER_ON); - command.parameters.PushBack(0x00); - return Transmit(command, false); - } - - return CCECCommandHandler::TransmitImageViewOn(iInitiator, iDestination); + cec_command response; + cec_command::Format(response, iSource, iDestination, CEC_OPCODE_VENDOR_COMMAND); + response.PushBack(SL_COMMAND_CONNECT_ACCEPT); + response.PushBack((uint8_t)iSource); + Transmit(response, false); } -bool CSLCommandHandler::HandleActiveSource(const cec_command &command) +void CSLCommandHandler::SetLGDeckStatus(void) { - if (command.parameters.size == 2) - { - uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]); - if (iAddress == 0) - return m_processor->GetPrimaryDevice()->TransmitPhysicalAddress(); - else - return m_processor->SetActiveSource(iAddress); - } + /* LG TVs only route keypresses when the deck status is set to 0x20 */ + CCECBusDevice *device = m_processor->GetDeviceByType(CEC_DEVICE_TYPE_PLAYBACK_DEVICE); + if (device) + ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG); - return true; + device = m_processor->GetDeviceByType(CEC_DEVICE_TYPE_RECORDING_DEVICE); + if (device) + ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG); } diff --git a/src/lib/implementations/SLCommandHandler.h b/src/lib/implementations/SLCommandHandler.h index 5f7d9ca..48674cc 100644 --- a/src/lib/implementations/SLCommandHandler.h +++ b/src/lib/implementations/SLCommandHandler.h @@ -42,27 +42,29 @@ namespace CEC virtual ~CSLCommandHandler(void) {}; virtual cec_vendor_id GetVendorId(void) { return CEC_VENDOR_LG; }; - virtual bool HandleCommand(const cec_command &command); virtual void HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination); virtual bool HandleReceiveFailed(void); virtual bool InitHandler(void); protected: - virtual void SetLGDeckStatus(void); + virtual bool HandleActiveSource(const cec_command &command); + virtual bool HandleFeatureAbort(const cec_command &command); + virtual bool HandleGivePhysicalAddress(const cec_command &command); + virtual bool HandleVendorCommand(const cec_command &command); + virtual void HandleVendorCommand01(const cec_command &command); + virtual void TransmitVendorCommand0205(const cec_logical_address iSource, const cec_logical_address iDestination); + virtual void HandleVendorCommandPowerOn(const cec_command &command); - virtual void HandleVendorCommandSLConnect(const cec_command &command); virtual void HandleVendorCommandPowerOnStatus(const cec_command &command); - virtual void TransmitVendorCommand0205(const cec_logical_address iSource, const cec_logical_address iDestination); + virtual void HandleVendorCommandSLConnect(const cec_command &command); virtual void TransmitVendorCommand05(const cec_logical_address iSource, const cec_logical_address iDestination); - virtual bool HandleVendorCommand(const cec_command &command); - virtual bool TransmitLGVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination); - virtual bool HandleActiveSource(const cec_command &command); - virtual bool TransmitPowerOn(const cec_logical_address iInitiator, const cec_logical_address iDestination); + + virtual void SetLGDeckStatus(void); bool m_bAwaitingReceiveFailed; bool m_bSLEnabled; - bool m_bVendorIdSent; + bool m_bPowerStateReset; }; }; -- 2.34.1