From 82d1a9a150628b179d1ad501eb9a73feb3f6dd1d Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sat, 3 Dec 2011 22:47:52 +0100 Subject: [PATCH] cec: retry failed tranmissions --- src/lib/AdapterCommunication.h | 13 ++++++++- src/lib/CECProcessor.cpp | 50 +++++++++++++++++++--------------- src/lib/CECProcessor.h | 2 +- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/lib/AdapterCommunication.h b/src/lib/AdapterCommunication.h index 2ebffed..461ed58 100644 --- a/src/lib/AdapterCommunication.h +++ b/src/lib/AdapterCommunication.h @@ -62,7 +62,7 @@ namespace CEC uint8_t operator[](uint8_t pos) const { return packet[pos]; } uint8_t at(uint8_t pos) const { return packet[pos]; } uint8_t size(void) const { return packet.size; } - void clear(void) { state = ADAPTER_MESSAGE_STATE_UNKNOWN; transmit_timeout = 0; packet.Clear(); } + void clear(void) { state = ADAPTER_MESSAGE_STATE_UNKNOWN; transmit_timeout = 0; packet.Clear(); maxTries = 5; tries = 0; reply = MSGCODE_NOTHING; } void shift(uint8_t iShiftBy) { packet.Shift(iShiftBy); } void push_back(uint8_t add) { packet.PushBack(add); } cec_adapter_messagecode message(void) const { return packet.size >= 1 ? (cec_adapter_messagecode) (packet.At(0) & ~(MSGCODE_FRAME_EOM | MSGCODE_FRAME_ACK)) : MSGCODE_NOTHING; } @@ -72,7 +72,18 @@ namespace CEC cec_logical_address destination(void) const { return packet.size >= 2 ? (cec_logical_address) (packet.At(1) & 0xF) : CECDEVICE_UNKNOWN; }; bool is_error(void) const; void push_escaped(uint8_t byte); + bool needs_retry(void) const { return reply == MSGCODE_NOTHING || + reply == MSGCODE_RECEIVE_FAILED || + reply == MSGCODE_TIMEOUT_ERROR || + reply == MSGCODE_TRANSMIT_FAILED_ACK || + reply == MSGCODE_TRANSMIT_FAILED_LINE || + reply == MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA || + reply == MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE || + reply == MSGCODE_TRANSMIT_LINE_TIMEOUT; } + uint8_t maxTries; + uint8_t tries; + cec_adapter_messagecode reply; cec_datapacket packet; cec_adapter_message_state state; int32_t transmit_timeout; diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 3eb4734..571d02d 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -674,26 +674,29 @@ bool CCECProcessor::Transmit(CCECAdapterMessage *output) bool bReturn(false); CLockObject lock(&m_mutex); { - CLockObject msgLock(&output->mutex); - if (!m_communication || !m_communication->Write(output)) - return bReturn; - else + while (output->needs_retry() && ++output->tries <= output->maxTries) { - output->condition.Wait(&output->mutex); - if (output->state != ADAPTER_MESSAGE_STATE_SENT) - { - m_controller->AddLog(CEC_LOG_ERROR, "command was not sent"); + CLockObject msgLock(&output->mutex); + if (!m_communication || !m_communication->Write(output)) return bReturn; + else + { + output->condition.Wait(&output->mutex); + if (output->state != ADAPTER_MESSAGE_STATE_SENT) + { + m_controller->AddLog(CEC_LOG_ERROR, "command was not sent"); + return bReturn; + } } - } - if (output->transmit_timeout > 0) - { - if ((bReturn = WaitForTransmitSucceeded(output->size(), output->transmit_timeout)) == false) - m_controller->AddLog(CEC_LOG_DEBUG, "did not receive ack"); + if (output->transmit_timeout > 0) + { + if ((bReturn = WaitForTransmitSucceeded(output)) == false) + m_controller->AddLog(CEC_LOG_DEBUG, "did not receive ack"); + } + else + bReturn = true; } - else - bReturn = true; } return bReturn; @@ -712,20 +715,20 @@ void CCECProcessor::TransmitAbort(cec_logical_address address, cec_opcode opcode Transmit(command); } -bool CCECProcessor::WaitForTransmitSucceeded(uint8_t iLength, uint32_t iTimeout /* = 1000 */) +bool CCECProcessor::WaitForTransmitSucceeded(CCECAdapterMessage *message) { bool bError(false); bool bTransmitSucceeded(false); - uint8_t iPacketsLeft(iLength / 4); + uint8_t iPacketsLeft(message->size() / 4); int64_t iNow = GetTimeMs(); - int64_t iTargetTime = iNow + (uint64_t) iTimeout; + int64_t iTargetTime = iNow + message->transmit_timeout; - while (!bTransmitSucceeded && !bError && (iTimeout == 0 || iNow < iTargetTime)) + while (!bTransmitSucceeded && !bError && (message->transmit_timeout == 0 || iNow < iTargetTime)) { CCECAdapterMessage msg; - if (!m_communication->Read(msg, iTimeout > 0 ? (int32_t)(iTargetTime - iNow) : 1000)) + if (!m_communication->Read(msg, message->transmit_timeout > 0 ? (int32_t)(iTargetTime - iNow) : 1000)) { iNow = GetTimeMs(); continue; @@ -748,9 +751,11 @@ bool CCECProcessor::WaitForTransmitSucceeded(uint8_t iLength, uint32_t iTimeout continue; } - if ((bError = msg.is_error()) == false) + if (bError) + message->reply = msg.message(); + else { - m_controller->AddLog(bError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString()); + m_controller->AddLog(CEC_LOG_DEBUG, msg.ToString()); switch(msg.message()) { @@ -761,6 +766,7 @@ bool CCECProcessor::WaitForTransmitSucceeded(uint8_t iLength, uint32_t iTimeout case MSGCODE_TRANSMIT_SUCCEEDED: bTransmitSucceeded = (iPacketsLeft == 0); bError = !bTransmitSucceeded; + message->reply = MSGCODE_TRANSMIT_SUCCEEDED; break; default: if (ParseMessage(msg)) diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index c8c8262..309365b 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -134,7 +134,7 @@ namespace CEC bool FindLogicalAddressAudioSystem(void); void LogOutput(const cec_command &data); - bool WaitForTransmitSucceeded(uint8_t iLength, uint32_t iTimeout = 1000); + bool WaitForTransmitSucceeded(CCECAdapterMessage *message); bool ParseMessage(const CCECAdapterMessage &msg); void ParseCommand(cec_command &command); -- 2.34.1