Don't send commands if we know them to be unsupported. bugzid: 725
authorMark Kendall <mkendall@mythtv.org>
Fri, 20 Apr 2012 14:57:14 +0000 (15:57 +0100)
committerMark Kendall <mkendall@mythtv.org>
Fri, 20 Apr 2012 14:57:14 +0000 (15:57 +0100)
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
src/lib/adapter/AdapterCommunication.h
src/lib/adapter/USBCECAdapterCommunication.cpp
src/lib/adapter/USBCECAdapterCommunication.h
src/lib/adapter/USBCECAdapterMessage.cpp
src/lib/adapter/USBCECAdapterMessage.h
src/lib/adapter/USBCECAdapterMessageQueue.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h

index 3f91fbf4fbac1d723016353f3f206686866891d2..708536f3ae2c3eeaeca87b26eb117465ca68f388 100644 (file)
@@ -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 */)
index 160a0fd3c30c320f9d262e6b2725c48b61fc0673..cbbc7ff89ed3dc43cbc349769712a76c8a3ded32 100644 (file)
@@ -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
index ef80ed049731abe60fe886f67dcd91018a40ac89..f5bdc2f443dada92e3a4b0d57d87dc57b39d383c 100644 (file)
@@ -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;
index 9d125a7b1080fd1de958f5827d8cd8bb4e2ab39b..4c4cb43fd3ec5bc1e394c198c4d07ee6d48ccb71 100644 (file)
@@ -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);
index c23c21b24b91c016d5852b2c92a383af77597e67..e8c575da1a637416ec8510b379d7acbaf428e11f 100644 (file)
@@ -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;
 }
 
index 2b122602d79b4b13e7716924f0096b57b3e03953..4d571b10431dc3a4a295a4aa6d4c62fd18cc6760 100644 (file)
@@ -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 */
index 9c66051f5e368640e27bc128e5185b55839dd77a..8533af6f6a1c13a45db81c6570bd3710c42bda06 100644 (file)
@@ -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);
index cba201b678c86424271236753d5fec67a9ae943c..f340d54a96b8412799b0f3da993395bedc25114e 100644 (file)
@@ -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);
 }
index 2bd97302f1e047fbc9a2060c0284b768291acb24..9db9bd4d03b39c403496d77d3fd7cefe8ac2b3d0 100644 (file)
@@ -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);