From 050df0f96b49e7130629c26116632011a14fb331 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sat, 8 Oct 2011 12:36:05 +0200 Subject: [PATCH] cec: retransmit if needed. wait long enough for an ack message --- src/lib/CECProcessor.cpp | 37 ++++++++++++++++++++++++++----------- src/lib/CECProcessor.h | 2 +- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 6757f8a..85eb1de 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -237,10 +237,25 @@ bool CCECProcessor::TransmitFormatted(const cec_frame &data, bool bWaitForAck /* if (!m_communication || !m_communication->Write(data)) return false; - if (bWaitForAck && !WaitForAck()) + if (bWaitForAck) { - m_controller->AddLog(CEC_LOG_DEBUG, "did not receive ACK"); - return false; + uint64_t now = GetTimeMs(); + uint64_t target = now + 1000; + bool bError(false); + bool bGotAck(false); + + while (!bGotAck && now < target) + { + bGotAck = WaitForAck(&bError, (uint64_t) (target - now)); + now = GetTimeMs(); + + if (bError && now < target) + { + m_controller->AddLog(CEC_LOG_ERROR, "retransmitting previous frame"); + if (!m_communication->Write(data)) + return false; + } + } } return true; @@ -361,10 +376,10 @@ uint8_t CCECProcessor::GetSourceDestination(cec_logical_address destination /* = return ((uint8_t)m_iLogicalAddress << 4) + (uint8_t)destination; } -bool CCECProcessor::WaitForAck(uint32_t iTimeout /* = 1000 */) +bool CCECProcessor::WaitForAck(bool *bError, uint32_t iTimeout /* = 1000 */) { bool bGotAck(false); - bool bError(false); + *bError = false; int64_t iNow = GetTimeMs(); int64_t iTargetTime = iNow + (uint64_t) iTimeout; @@ -390,27 +405,27 @@ bool CCECProcessor::WaitForAck(uint32_t iTimeout /* = 1000 */) break; case MSGCODE_RECEIVE_FAILED: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_RECEIVE_FAILED"); - bError = true; + *bError = true; break; case MSGCODE_COMMAND_REJECTED: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_COMMAND_REJECTED"); - bError = true; + *bError = true; break; case MSGCODE_TRANSMIT_FAILED_LINE: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_LINE"); - bError = true; + *bError = true; break; case MSGCODE_TRANSMIT_FAILED_ACK: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_ACK"); - bError = true; + *bError = true; break; case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA"); - bError = true; + *bError = true; break; case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE"); - bError = true; + *bError = true; break; default: m_frameBuffer.Push(msg); diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 660fee0..ef2be9c 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -72,7 +72,7 @@ namespace CEC virtual uint8_t GetSourceDestination(cec_logical_address destination = CECDEVICE_BROADCAST) const; private: - bool WaitForAck(uint32_t iTimeout = 1000); + bool WaitForAck(bool *bError, uint32_t iTimeout = 1000); bool ParseMessage(cec_frame &msg); void ParseCurrentFrame(cec_frame &frame); -- 2.34.1