From 33dd87a962743d205ade8dc83693f23e94e36f03 Mon Sep 17 00:00:00 2001 From: Mark Kendall Date: Fri, 20 Apr 2012 15:57:14 +0100 Subject: [PATCH] Don't send commands if we know them to be unsupported. bugzid: 725 The bulk of the change is to move the retry handling into CECProcessor so that we have access to the unsupported features. --- src/lib/CECProcessor.cpp | 17 +++++++++++++++-- src/lib/adapter/AdapterCommunication.h | 7 +++---- src/lib/adapter/USBCECAdapterCommunication.cpp | 14 +++++--------- src/lib/adapter/USBCECAdapterCommunication.h | 2 +- src/lib/adapter/USBCECAdapterMessage.cpp | 13 +------------ src/lib/adapter/USBCECAdapterMessage.h | 8 ++------ src/lib/adapter/USBCECAdapterMessageQueue.cpp | 5 +---- src/lib/devices/CECBusDevice.cpp | 4 +++- src/lib/devices/CECBusDevice.h | 2 +- 9 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 3f91fbf..708536f 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -931,8 +931,21 @@ bool CCECProcessor::Transmit(const cec_command &data) iMaxTries = m_busDevices[data.initiator]->GetHandler()->GetTransmitRetries() + 1; } - return m_communication->Write(data, iMaxTries, m_iStandardLineTimeout, m_iRetryLineTimeout) - == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bool bRetry(true); + uint8_t iTries(0); + uint8_t iLineTimeout = m_iStandardLineTimeout; + cec_adapter_message_state adapterState = ADAPTER_MESSAGE_STATE_UNKNOWN; + + while (bRetry && ++iTries < iMaxTries) + { + if (m_busDevices[data.initiator]->IsUnsupportedFeature(data.opcode)) + return false; + + adapterState = m_communication->Write(data, bRetry, iLineTimeout); + iLineTimeout = m_iRetryLineTimeout; + } + + return adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED; } void CCECProcessor::TransmitAbort(cec_logical_address address, cec_opcode opcode, cec_abort_reason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */) diff --git a/src/lib/adapter/AdapterCommunication.h b/src/lib/adapter/AdapterCommunication.h index 160a0fd..cbbc7ff 100644 --- a/src/lib/adapter/AdapterCommunication.h +++ b/src/lib/adapter/AdapterCommunication.h @@ -101,12 +101,11 @@ namespace CEC /*! * @brief Write a cec_command to the adapter * @param data The command to write - * @param iMaxTries The maximum number of tries - * @param iLineTimeout The line timeout for the first try - * @param iRetryLineTimeout The line timeout for each next try + * @param bRetry The command can be retried + * @param iLineTimeout The line timeout to be used * @return The last state of the transmitted command */ - virtual cec_adapter_message_state Write(const cec_command &data, uint8_t iMaxTries, uint8_t iLineTimeout = 3, uint8_t iRetryLineTimeout = 3) = 0; + virtual cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout = 3) = 0; /*! * @brief Change the current line timeout on the CEC bus diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index ef80ed0..f5bdc2f 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -174,25 +174,21 @@ void CUSBCECAdapterCommunication::Close(void) m_port->Close(); } -cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, uint8_t iMaxTries, uint8_t iLineTimeout /* = 3 */, uint8_t iRetryLineTimeout /* = 3 */) +cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout) { cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN); if (!IsRunning()) return retVal; - CCECAdapterMessage *output = new CCECAdapterMessage(data, iMaxTries, iLineTimeout, iRetryLineTimeout); + CCECAdapterMessage *output = new CCECAdapterMessage(data, iLineTimeout); /* mark as waiting for an ack from the destination */ MarkAsWaiting(data.destination); /* send the message */ - bool bRetry(true); - while (bRetry && ++output->tries < output->maxTries) - { - bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0; - if (bRetry) - Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); - } + bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0; + if (bRetry) + Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); retVal = output->state; delete output; diff --git a/src/lib/adapter/USBCECAdapterCommunication.h b/src/lib/adapter/USBCECAdapterCommunication.h index 9d125a7..4c4cb43 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.h +++ b/src/lib/adapter/USBCECAdapterCommunication.h @@ -70,7 +70,7 @@ namespace CEC void Close(void); bool IsOpen(void); CStdString GetError(void) const; - cec_adapter_message_state Write(const cec_command &data, uint8_t iMaxTries, uint8_t iLineTimeout = 3, uint8_t iRetryLineTimeout = 3); + cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout = 3); bool StartBootloader(void); bool SetAckMask(uint16_t iMask); diff --git a/src/lib/adapter/USBCECAdapterMessage.cpp b/src/lib/adapter/USBCECAdapterMessage.cpp index c23c21b..e8c575d 100644 --- a/src/lib/adapter/USBCECAdapterMessage.cpp +++ b/src/lib/adapter/USBCECAdapterMessage.cpp @@ -41,7 +41,7 @@ CCECAdapterMessage::CCECAdapterMessage(void) Clear(); } -CCECAdapterMessage::CCECAdapterMessage(const cec_command &command, uint8_t iMaxTries /* = 1 */, uint8_t iLineTimeout /* = 3 */, uint8_t iRetryLineTimeout /* = 3 */) +CCECAdapterMessage::CCECAdapterMessage(const cec_command &command, uint8_t iLineTimeout /* = 3 */) { Clear(); @@ -88,15 +88,7 @@ CCECAdapterMessage::CCECAdapterMessage(const cec_command &command, uint8_t iMaxT // set timeout transmit_timeout = command.transmit_timeout; - /* set the number of retries */ - if (command.opcode == CEC_OPCODE_NONE) //TODO - maxTries = 1; - else if (command.initiator != CECDEVICE_BROADCAST) - maxTries = iMaxTries; - lineTimeout = iLineTimeout; - retryTimeout = iRetryLineTimeout; - tries = 0; } CStdString CCECAdapterMessage::ToString(void) const @@ -257,10 +249,7 @@ void CCECAdapterMessage::Clear(void) transmit_timeout = CEC_DEFAULT_TRANSMIT_TIMEOUT; response.Clear(); packet.Clear(); - maxTries = CEC_DEFAULT_TRANSMIT_RETRIES + 1; - tries = 0; lineTimeout = 3; - retryTimeout = 3; bNextByteIsEscaped = false; } diff --git a/src/lib/adapter/USBCECAdapterMessage.h b/src/lib/adapter/USBCECAdapterMessage.h index 2b12260..4d571b1 100644 --- a/src/lib/adapter/USBCECAdapterMessage.h +++ b/src/lib/adapter/USBCECAdapterMessage.h @@ -60,11 +60,9 @@ namespace CEC /*! * @brief Create a message with a command that is to be transmitted over the CEC line. * @param command The command to transmit. - * @param iMaxTries The maximum number of tries. - * @param iLineTimeout The line timeout to use when sending this message the first time. - * @param iRetryLineTimeout The line timeout to use when retrying to send this message. + * @param iLineTimeout The line timeout to use when sending this message. */ - CCECAdapterMessage(const cec_command &command, uint8_t iMaxTries = 1, uint8_t iLineTimeout = 3, uint8_t iRetryLineTimeout = 3); + CCECAdapterMessage(const cec_command &command, uint8_t iLineTimeout = 3); /*! * @return the message as human readable string. @@ -196,13 +194,11 @@ namespace CEC cec_adapter_messagecode Reply(void) const; uint8_t maxTries; /**< the maximum number of times to try to send this message */ - uint8_t tries; /**< the amount of times this message has been sent */ cec_datapacket response; /**< the response to this message */ cec_datapacket packet; /**< the actual data */ cec_adapter_message_state state; /**< the current state of this message */ int32_t transmit_timeout; /**< the timeout to use when sending this message */ uint8_t lineTimeout; /**< the default CEC line timeout to use when sending this message */ - uint8_t retryTimeout; /**< the CEC line timeout to use when retrying to send this message */ private: bool bNextByteIsEscaped; /**< true when the next byte that is added will be escaped, false otherwise */ diff --git a/src/lib/adapter/USBCECAdapterMessageQueue.cpp b/src/lib/adapter/USBCECAdapterMessageQueue.cpp index 9c66051..8533af6 100644 --- a/src/lib/adapter/USBCECAdapterMessageQueue.cpp +++ b/src/lib/adapter/USBCECAdapterMessageQueue.cpp @@ -279,10 +279,7 @@ bool CCECAdapterMessageQueue::Write(CCECAdapterMessage *msg) /* set the correct line timeout */ if (msg->IsTranmission()) { - if (msg->tries == 1) - m_com->SetLineTimeout(msg->lineTimeout); - else - m_com->SetLineTimeout(msg->retryTimeout); + m_com->SetLineTimeout(msg->lineTimeout); } CCECAdapterMessageQueueEntry *entry(NULL); diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index cba201b..f340d54 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -1012,8 +1012,9 @@ bool CCECBusDevice::TransmitKeyRelease(bool bWait /* = true */) return bReturn; } -bool CCECBusDevice::IsUnsupportedFeature(cec_opcode opcode) const +bool CCECBusDevice::IsUnsupportedFeature(cec_opcode opcode) { + CLockObject lock(m_mutex); bool bUnsupported = (m_unsupportedFeatures.find(opcode) != m_unsupportedFeatures.end()); if (bUnsupported) CLibCEC::AddLog(CEC_LOG_NOTICE, "'%s' is marked as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName()); @@ -1022,6 +1023,7 @@ bool CCECBusDevice::IsUnsupportedFeature(cec_opcode opcode) const void CCECBusDevice::SetUnsupportedFeature(cec_opcode opcode) { + CLockObject lock(m_mutex); CLibCEC::AddLog(CEC_LOG_DEBUG, "marking opcode '%s' as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName()); m_unsupportedFeatures.insert(opcode); } diff --git a/src/lib/devices/CECBusDevice.h b/src/lib/devices/CECBusDevice.h index 2bd9730..9db9bd4 100644 --- a/src/lib/devices/CECBusDevice.h +++ b/src/lib/devices/CECBusDevice.h @@ -72,7 +72,7 @@ namespace CEC virtual bool MyLogicalAddressContains(cec_logical_address address) const; virtual cec_bus_device_status GetStatus(bool bForcePoll = false, bool bSuppressPoll = false); virtual bool IsActiveSource(void) const { return m_bActiveSource; } - virtual bool IsUnsupportedFeature(cec_opcode opcode) const; + virtual bool IsUnsupportedFeature(cec_opcode opcode); virtual void SetUnsupportedFeature(cec_opcode opcode); virtual void HandlePoll(cec_logical_address destination); virtual void HandlePollFrom(cec_logical_address initiator); -- 2.34.1