X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fimplementations%2FCECCommandHandler.cpp;h=d23340fed66aa32e21b551d40f9914397ee712cf;hb=496897540ebcc6fc13b346aa5e08f2148a2770c7;hp=03165e9c2cf91ec613a4def5b4cd901f2dbcff5e;hpb=5d19989ff572f154b7c42f2151390b02dc106983;p=deb_libcec.git diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 03165e9..d23340f 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -30,15 +30,17 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../devices/CECAudioSystem.h" -#include "../devices/CECPlaybackDevice.h" -#include "../CECClient.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" -#include "../CECTypeUtils.h" -#include "../platform/util/util.h" + +#include "lib/devices/CECBusDevice.h" +#include "lib/devices/CECAudioSystem.h" +#include "lib/devices/CECPlaybackDevice.h" +#include "lib/CECClient.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" +#include "lib/CECTypeUtils.h" +#include "lib/platform/util/util.h" using namespace CEC; using namespace std; @@ -47,23 +49,21 @@ using namespace PLATFORM; #define LIB_CEC m_busDevice->GetProcessor()->GetLib() #define ToString(p) CCECTypeUtils::ToString(p) -CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice) : +CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice, + int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */, + int32_t iTransmitWait /* = CEC_DEFAULT_TRANSMIT_WAIT */, + int8_t iTransmitRetries /* = CEC_DEFAULT_TRANSMIT_RETRIES */, + int64_t iActiveSourcePending /* = 0 */) : m_busDevice(busDevice), m_processor(m_busDevice->GetProcessor()), - m_iTransmitTimeout(CEC_DEFAULT_TRANSMIT_TIMEOUT), - m_iTransmitWait(CEC_DEFAULT_TRANSMIT_WAIT), - m_iTransmitRetries(CEC_DEFAULT_TRANSMIT_RETRIES), + m_iTransmitTimeout(iTransmitTimeout), + m_iTransmitWait(iTransmitWait), + m_iTransmitRetries(iTransmitRetries), m_bHandlerInited(false), m_bOPTSendDeckStatusUpdateOnActiveSource(false), m_vendorId(CEC_VENDOR_UNKNOWN), - m_waitForResponse(new CWaitForResponse), - m_iActiveSourcePending(0) -{ -} - -CCECCommandHandler::~CCECCommandHandler(void) + m_iActiveSourcePending(iActiveSourcePending) { - DELETE_AND_NULL(m_waitForResponse); } bool CCECCommandHandler::HandleCommand(const cec_command &command) @@ -195,7 +195,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) } if (iHandled == COMMAND_HANDLED) - m_waitForResponse->Received((command.opcode == CEC_OPCODE_FEATURE_ABORT && command.parameters.size > 0) ? (cec_opcode)command.parameters[0] : command.opcode); + m_busDevice->SignalOpcode((command.opcode == CEC_OPCODE_FEATURE_ABORT && command.parameters.size > 0) ? (cec_opcode)command.parameters[0] : command.opcode); else UnhandledCommand(command, (cec_abort_reason)iHandled); @@ -269,7 +269,7 @@ int CCECCommandHandler::HandleGetCecVersion(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitCECVersion(command.initiator)) + if (device && device->TransmitCECVersion(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -282,7 +282,7 @@ int CCECCommandHandler::HandleGiveAudioStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECAudioSystem *device = CCECBusDevice::AsAudioSystem(GetDevice(command.destination)); - if (device && device->TransmitAudioStatus(command.initiator)) + if (device && device->TransmitAudioStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -295,7 +295,7 @@ int CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECPlaybackDevice *device = CCECBusDevice::AsPlaybackDevice(GetDevice(command.destination)); - if (device && device->TransmitDeckStatus(command.initiator)) + if (device && device->TransmitDeckStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -308,7 +308,7 @@ int CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitPowerState(command.initiator)) + if (device && device->TransmitPowerState(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -321,7 +321,7 @@ int CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitVendorID(command.initiator)) + if (device && device->TransmitVendorID(command.initiator, true, true)) return COMMAND_HANDLED; } @@ -333,7 +333,7 @@ int CCECCommandHandler::HandleGiveOSDName(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitOSDName(command.initiator)) + if (device && device->TransmitOSDName(command.initiator, true)) return COMMAND_HANDLED; } @@ -345,7 +345,7 @@ int CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitPhysicalAddress()) + if (device && device->TransmitPhysicalAddress(true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -358,7 +358,7 @@ int CCECCommandHandler::HandleGiveMenuLanguage(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitSetMenuLanguage(command.initiator)) + if (device && device->TransmitSetMenuLanguage(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -371,7 +371,7 @@ int CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &comma if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECAudioSystem *device = CCECBusDevice::AsAudioSystem(GetDevice(command.destination)); - if (device && device->TransmitSystemAudioModeStatus(command.initiator)) + if (device && device->TransmitSystemAudioModeStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -381,7 +381,14 @@ int CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &comma int CCECCommandHandler::HandleImageViewOn(const cec_command &command) { - m_processor->GetDevice(command.initiator)->MarkAsActiveSource(); + CCECBusDevice *device = GetDevice(command.destination); + if (device && (device->GetCurrentStatus() == CEC_DEVICE_STATUS_PRESENT || + device->GetCurrentStatus() == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)) + { + if (device->GetCurrentPowerStatus() == CEC_POWER_STATUS_STANDBY || + device->GetCurrentPowerStatus() == CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY) + device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); + } return COMMAND_HANDLED; } @@ -406,7 +413,7 @@ int CCECCommandHandler::HandleMenuRequest(const cec_command &command) device->SetMenuState(CEC_MENU_STATE_DEACTIVATED); } } - if (device->TransmitMenuState(command.initiator)) + if (device->TransmitMenuState(command.initiator, true)) return COMMAND_HANDLED; } return CEC_ABORT_REASON_INVALID_OPERAND; @@ -469,7 +476,7 @@ int CCECCommandHandler::HandleRequestActiveSource(const cec_command &command) vector devices; for (size_t iDevicePtr = 0; iDevicePtr < GetMyDevices(devices); iDevicePtr++) - devices[iDevicePtr]->TransmitActiveSource(); + devices[iDevicePtr]->TransmitActiveSource(true); } return COMMAND_HANDLED; @@ -591,13 +598,13 @@ int CCECCommandHandler::HandleSystemAudioModeRequest(const cec_command &command) CCECBusDevice *newActiveDevice = GetDeviceByPhysicalAddress(iNewAddress); if (newActiveDevice) newActiveDevice->MarkAsActiveSource(); - if (device->TransmitSetSystemAudioMode(command.initiator)) + if (device->TransmitSetSystemAudioMode(command.initiator, true)) return COMMAND_HANDLED; } else { device->SetSystemAudioModeStatus(CEC_SYSTEM_AUDIO_STATUS_OFF); - if (device->TransmitSetSystemAudioMode(command.initiator)) + if (device->TransmitSetSystemAudioMode(command.initiator, true)) return COMMAND_HANDLED; } } @@ -666,9 +673,6 @@ int CCECCommandHandler::HandleUserControlPressed(const cec_command &command) CCECClient *client = device->GetClient(); if (client) - client->AddKey(); - - if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX) client->SetCurrentButton((cec_user_control_code) command.parameters[0]); if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER || @@ -811,7 +815,7 @@ bool CCECCommandHandler::TransmitImageViewOn(const cec_logical_address iInitiato cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_IMAGE_VIEW_ON); - return Transmit(command); + return Transmit(command, false, false); } bool CCECCommandHandler::TransmitStandby(const cec_logical_address iInitiator, const cec_logical_address iDestination) @@ -819,7 +823,7 @@ bool CCECCommandHandler::TransmitStandby(const cec_logical_address iInitiator, c cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_STANDBY); - return Transmit(command); + return Transmit(command, false, false); } bool CCECCommandHandler::TransmitRequestActiveSource(const cec_logical_address iInitiator, bool bWaitForResponse /* = true */) @@ -827,7 +831,7 @@ bool CCECCommandHandler::TransmitRequestActiveSource(const cec_logical_address i cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_REQUEST_ACTIVE_SOURCE); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestCecVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -835,7 +839,7 @@ bool CCECCommandHandler::TransmitRequestCecVersion(const cec_logical_address iIn cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GET_CEC_VERSION); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestMenuLanguage(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -843,7 +847,7 @@ bool CCECCommandHandler::TransmitRequestMenuLanguage(const cec_logical_address i cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GET_MENU_LANGUAGE); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -851,7 +855,7 @@ bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iIniti cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_OSD_NAME); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -859,7 +863,7 @@ bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_addres cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_PHYSICAL_ADDRESS); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -867,7 +871,7 @@ bool CCECCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iI cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_POWER_STATUS); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -875,26 +879,26 @@ bool CCECCommandHandler::TransmitRequestVendorId(const cec_logical_address iInit cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } -bool CCECCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress) +bool CCECCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_ACTIVE_SOURCE); command.parameters.PushBack((uint8_t) ((iPhysicalAddress >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) (iPhysicalAddress & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion) +bool CCECCommandHandler::TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_CEC_VERSION); command.parameters.PushBack((uint8_t)cecVersion); - return Transmit(command); + return Transmit(command, false, bIsReply); } bool CCECCommandHandler::TransmitInactiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress) @@ -904,29 +908,29 @@ bool CCECCommandHandler::TransmitInactiveSource(const cec_logical_address iIniti command.parameters.PushBack((iPhysicalAddress >> 8) & 0xFF); command.parameters.PushBack(iPhysicalAddress & 0xFF); - return Transmit(command); + return Transmit(command, false, false); } -bool CCECCommandHandler::TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState) +bool CCECCommandHandler::TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_MENU_STATUS); command.parameters.PushBack((uint8_t)menuState); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, CStdString strDeviceName) +bool CCECCommandHandler::TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, std::string strDeviceName, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_OSD_NAME); for (size_t iPtr = 0; iPtr < strDeviceName.length(); iPtr++) command.parameters.PushBack(strDeviceName.at(iPtr)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage) +bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_OSD_STRING); @@ -938,10 +942,10 @@ bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, for (size_t iPtr = 0; iPtr < iLen; iPtr++) command.parameters.PushBack(strMessage[iPtr]); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type) +bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_REPORT_PHYSICAL_ADDRESS); @@ -949,10 +953,10 @@ bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInit command.parameters.PushBack((uint8_t) (iPhysicalAddress & 0xFF)); command.parameters.PushBack((uint8_t) (type)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3]) +bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3], bool bIsReply) { cec_command command; command.Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_SET_MENU_LANGUAGE); @@ -960,27 +964,27 @@ bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInit command.parameters.PushBack((uint8_t) lang[1]); command.parameters.PushBack((uint8_t) lang[2]); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination) +bool CCECCommandHandler::TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_NONE); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state) +bool CCECCommandHandler::TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_REPORT_POWER_STATUS); command.parameters.PushBack((uint8_t) state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId) +bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_DEVICE_VENDOR_ID); @@ -989,53 +993,58 @@ bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, command.parameters.PushBack((uint8_t) (((uint64_t)iVendorId >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) ((uint64_t)iVendorId & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state) +bool CCECCommandHandler::TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_REPORT_AUDIO_STATUS); command.parameters.PushBack(state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state) +bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_SYSTEM_AUDIO_MODE); command.parameters.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetStreamPath(uint16_t iStreamPath) +bool CCECCommandHandler::TransmitSetStreamPath(uint16_t iStreamPath, bool bIsReply) { + if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "only the TV is allowed to send CEC_OPCODE_SET_STREAM_PATH"); + return false; + } cec_command command; cec_command::Format(command, m_busDevice->GetLogicalAddress(), CECDEVICE_BROADCAST, CEC_OPCODE_SET_STREAM_PATH); command.parameters.PushBack((uint8_t) ((iStreamPath >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) (iStreamPath & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state) +bool CCECCommandHandler::TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS); command.parameters.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state) +bool CCECCommandHandler::TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_DECK_STATUS); command.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } bool CCECCommandHandler::TransmitKeypress(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_user_control_code key, bool bWait /* = true */) @@ -1044,7 +1053,7 @@ bool CCECCommandHandler::TransmitKeypress(const cec_logical_address iInitiator, cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_USER_CONTROL_PRESSED); command.parameters.PushBack((uint8_t)key); - return Transmit(command, !bWait); + return Transmit(command, !bWait, false); } bool CCECCommandHandler::TransmitKeyRelease(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWait /* = true */) @@ -1052,10 +1061,10 @@ bool CCECCommandHandler::TransmitKeyRelease(const cec_logical_address iInitiator cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_USER_CONTROL_RELEASE); - return Transmit(command, !bWait); + return Transmit(command, !bWait, false); } -bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait /* = false */) +bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait, bool bIsReply) { bool bReturn(false); cec_opcode expectedResponse(cec_command::GetResponseOpcode(command.opcode)); @@ -1072,12 +1081,12 @@ bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait /* = uint8_t iTries(0), iMaxTries(!command.opcode_set ? 1 : m_iTransmitRetries + 1); while (!bReturn && ++iTries <= iMaxTries && !m_busDevice->IsUnsupportedFeature(command.opcode)) { - if ((bReturn = m_processor->Transmit(command)) == true) + if ((bReturn = m_processor->Transmit(command, bIsReply)) == true) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "command transmitted"); if (bExpectResponse) { - bReturn = m_waitForResponse->Wait(expectedResponse); + bReturn = m_busDevice->WaitForOpcode(expectedResponse); LIB_CEC->AddLog(CEC_LOG_DEBUG, bReturn ? "expected response received (%X: %s)" : "expected response not received (%X: %s)", (int)expectedResponse, ToString(expectedResponse)); } } @@ -1102,17 +1111,19 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f LIB_CEC->AddLog(CEC_LOG_DEBUG, "transmitting delayed activate source command"); } - - // clear previous pending active source command - m_iActiveSourcePending = 0; } // update the power state and menu state m_busDevice->SetPowerStatus(CEC_POWER_STATUS_ON); - m_busDevice->SetMenuState(CEC_MENU_STATE_ACTIVATED); // TODO: LG + m_busDevice->SetMenuState(CEC_MENU_STATE_ACTIVATED); + + // vendor specific hook + VendorPreActivateSourceHook(); // power on the TV - bool bActiveSourceFailed = !m_busDevice->TransmitImageViewOn(); + bool bActiveSourceFailed(false); + if (m_processor->GetDevice(CECDEVICE_TV)->GetPowerStatus(m_busDevice->GetLogicalAddress()) != CEC_POWER_STATUS_ON) + bActiveSourceFailed = !m_busDevice->TransmitImageViewOn(); // check if we're allowed to switch sources bool bSourceSwitchAllowed = SourceSwitchAllowed(); @@ -1122,15 +1133,15 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f // switch sources (if allowed) if (!bActiveSourceFailed && bSourceSwitchAllowed) { - bActiveSourceFailed = !m_busDevice->TransmitActiveSource() || - !m_busDevice->TransmitMenuState(CECDEVICE_TV); + bActiveSourceFailed = !m_busDevice->TransmitActiveSource(false) || + !m_busDevice->TransmitMenuState(CECDEVICE_TV, false); // update the deck status for playback devices if (!bActiveSourceFailed) { CCECPlaybackDevice *playbackDevice = m_busDevice->AsPlaybackDevice(); if (playbackDevice && SendDeckStatusUpdateOnActiveSource()) - bActiveSourceFailed = !playbackDevice->TransmitDeckStatus(CECDEVICE_TV); + bActiveSourceFailed = !playbackDevice->TransmitDeckStatus(CECDEVICE_TV, false); } } @@ -1139,9 +1150,16 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f { LIB_CEC->AddLog(CEC_LOG_DEBUG, "failed to make '%s' the active source. will retry later", m_busDevice->GetLogicalAddressName()); CLockObject lock(m_mutex); - m_iActiveSourcePending = GetTimeMs() + (int64_t)CEC_ACTIVE_SOURCE_SWITCH_RETRY_TIME_MS; + if (m_iActiveSourcePending == 0) + m_iActiveSourcePending = GetTimeMs() + (int64_t)CEC_ACTIVE_SOURCE_SWITCH_RETRY_TIME_MS; return false; } + else + { + CLockObject lock(m_mutex); + // clear previous pending active source command + m_iActiveSourcePending = 0; + } // mark the handler as initialised CLockObject lock(m_mutex); @@ -1150,7 +1168,8 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f return true; } -void CCECCommandHandler::SignalOpcode(cec_opcode opcode) +void CCECCommandHandler::ScheduleActivateSource(uint64_t iDelay) { - m_waitForResponse->Received(opcode); + CLockObject lock(m_mutex); + m_iActiveSourcePending = GetTimeMs() + iDelay; }