cec: wait 500 ms before trying to retransmit a command. always wait for the result...
[deb_libcec.git] / src / lib / CECProcessor.cpp
index 8c808ae8b390cb20e4461e466d20038d9944a1e3..b54426cb5d255342fcee9b1bee435c1f26dda536 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the libCEC(R) library.
  *
- * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
  * libCEC(R) is an original work, containing original code.
  *
  * libCEC(R) is a trademark of Pulse-Eight Limited.
@@ -41,6 +41,7 @@
 #include "devices/CECTV.h"
 #include "implementations/CECCommandHandler.h"
 #include "LibCEC.h"
+#include "platform/util/timeutils.h"
 
 using namespace CEC;
 using namespace std;
@@ -147,43 +148,37 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint
 
   uint64_t iNow = GetTimeMs();
   uint64_t iTarget = iTimeoutMs > 0 ? iNow + iTimeoutMs : iNow + CEC_DEFAULT_TRANSMIT_WAIT;
+  unsigned iConnectTry(0), iPingTry(0), iFwVersionTry(0);
+  bool bConnected(false), bPinged(false);
 
   /* open a new connection */
-  if ((bReturn = m_communication->Open(strPort, iBaudRate, iTimeoutMs)) == false)
-    CLibCEC::AddLog(CEC_LOG_ERROR, "could not open a connection");
+  while (iNow < iTarget && (bConnected = m_communication->Open(strPort, iBaudRate, iTimeoutMs)) == false)
+  {
+    CLibCEC::AddLog(CEC_LOG_ERROR, "could not open a connection (try %d)", ++iConnectTry);
+    Sleep(500);
+    iNow = GetTimeMs();
+  }
 
   /* try to ping the adapter */
-  bool bPingOk(false);
-  unsigned iPingTry(0), iFwVersionTry(0);
-  uint16_t iFirmwareVersion(CEC_FW_VERSION_UNKNOWN);
-  while ((!bPingOk || iFirmwareVersion == CEC_FW_VERSION_UNKNOWN) && iTarget > iNow)
+  while (bConnected && iNow < iTarget && (bPinged = m_communication->PingAdapter()) == false)
   {
-    if (!bPingOk)
-    {
-      if ((bPingOk = m_communication->PingAdapter()) == false)
-      {
-        CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond correctly to a ping (try %d)", ++iPingTry);
-        Sleep(500);
-      }
-    }
-
-    if (bPingOk)
-    {
-      if ((iFirmwareVersion = m_communication->GetFirmwareVersion()) == CEC_FW_VERSION_UNKNOWN)
-      {
-        CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond with a correct firmware version (try %d)", ++iFwVersionTry);
-        Sleep(500);
-      }
-      else
-      {
-        CLibCEC::AddLog(CEC_LOG_NOTICE, "CEC Adapter firmware version: %d", iFirmwareVersion);
-        bReturn = true;
-      }
-    }
+    CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond correctly to a ping (try %d)", ++iPingTry);
+    Sleep(500);
+    iNow = GetTimeMs();
+  }
 
+  /* try to read the firmware version */
+  uint16_t iFirmwareVersion(CEC_FW_VERSION_UNKNOWN);
+  while (bPinged && iNow < iTarget && (iFirmwareVersion = m_communication->GetFirmwareVersion()) == CEC_FW_VERSION_UNKNOWN)
+  {
+    CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond with a correct firmware version (try %d)", ++iFwVersionTry);
+    Sleep(500);
     iNow = GetTimeMs();
   }
 
+  if ((bReturn = iFirmwareVersion != CEC_FW_VERSION_UNKNOWN) == true)
+    CLibCEC::AddLog(CEC_LOG_NOTICE, "connected to the CEC adapter. firmware version = %d", iFirmwareVersion);
+
   return bReturn;
 }
 
@@ -329,7 +324,7 @@ bool CCECProcessor::ChangeDeviceType(cec_device_type from, cec_device_type to)
     if (previousDevice && newDevice)
     {
       newDevice->SetDeviceStatus(CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
-      previousDevice->SetDeviceStatus(CEC_DEVICE_STATUS_UNKNOWN);
+      previousDevice->SetDeviceStatus(CEC_DEVICE_STATUS_NOT_PRESENT);
 
       newDevice->SetCecVersion(previousDevice->GetCecVersion(false));
       previousDevice->SetCecVersion(CEC_VERSION_UNKNOWN);
@@ -479,6 +474,12 @@ bool CCECProcessor::SetActiveSource(cec_device_type type /* = CEC_DEVICE_TYPE_RE
   {
     bReturn = m_busDevices[addr]->TransmitActiveSource();
 
+    if (bReturn)
+    {
+      m_busDevices[addr]->SetMenuState(CEC_MENU_STATE_ACTIVATED);
+      m_busDevices[addr]->TransmitMenuState(CECDEVICE_TV);
+    }
+
     if (bReturn && (m_busDevices[addr]->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE ||
         m_busDevices[addr]->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE) &&
         m_busDevices[addr]->GetHandler()->SendDeckStatusUpdateOnActiveSource())
@@ -894,6 +895,8 @@ bool CCECProcessor::Transmit(CCECAdapterMessage *output)
       if (output->tries > 0)
         m_communication->SetLineTimeout(m_iRetryLineTimeout);
       bReturn = m_communication->Write(output);
+      if (!bReturn)
+        Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
     }while (!bReturn && output->transmit_timeout > 0 && output->NeedsRetry() && ++output->tries < output->maxTries);
   }