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 */)
/*!
* @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
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;
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);
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();
// 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
transmit_timeout = CEC_DEFAULT_TRANSMIT_TIMEOUT;
response.Clear();
packet.Clear();
- maxTries = CEC_DEFAULT_TRANSMIT_RETRIES + 1;
- tries = 0;
lineTimeout = 3;
- retryTimeout = 3;
bNextByteIsEscaped = false;
}
/*!
* @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.
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 */
/* 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);
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());
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);
}
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);