cec: set line timeout when (re)transmitting. don't sleep after transmitting
[deb_libcec.git] / src / lib / AdapterCommunication.cpp
index 32ceeafc02e5835be628af9a2d8e140056c838b0..fc650f0651f82a986dd2cfe7df730d47dfa4b033 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "AdapterCommunication.h"
 
-#include "LibCEC.h"
+#include "CECProcessor.h"
 #include "platform/serialport.h"
 #include "util/StdString.h"
 #include "platform/timeutils.h"
@@ -183,30 +183,37 @@ CStdString CCECAdapterMessage::MessageCodeAsString(void) const
 CStdString CCECAdapterMessage::ToString(void) const
 {
   CStdString strMsg;
-  strMsg = MessageCodeAsString();
-
-  switch (message())
+  if (size() == 0)
   {
-  case MSGCODE_TIMEOUT_ERROR:
-  case MSGCODE_HIGH_ERROR:
-  case MSGCODE_LOW_ERROR:
+    strMsg = "empty message";
+  }
+  else
+  {
+    strMsg = MessageCodeAsString();
+
+    switch (message())
     {
-      int iLine      = (size() >= 3) ? (at(1) << 8) | at(2) : 0;
-      uint32_t iTime = (size() >= 7) ? (at(3) << 24) | (at(4) << 16) | (at(5) << 8) | at(6) : 0;
-      strMsg.AppendFormat(" line:%i", iLine);
-      strMsg.AppendFormat(" time:%u", iTime);
+    case MSGCODE_TIMEOUT_ERROR:
+    case MSGCODE_HIGH_ERROR:
+    case MSGCODE_LOW_ERROR:
+      {
+        int iLine      = (size() >= 3) ? (at(1) << 8) | at(2) : 0;
+        uint32_t iTime = (size() >= 7) ? (at(3) << 24) | (at(4) << 16) | (at(5) << 8) | at(6) : 0;
+        strMsg.AppendFormat(" line:%i", iLine);
+        strMsg.AppendFormat(" time:%u", iTime);
+      }
+      break;
+    case MSGCODE_FRAME_START:
+      if (size() >= 2)
+        strMsg.AppendFormat(" initiator:%1x destination:%1x ack:%s %s", initiator(), destination(), ack() ? "high" : "low", eom() ? "eom" : "");
+      break;
+    case MSGCODE_FRAME_DATA:
+      if (size() >= 2)
+        strMsg.AppendFormat(" %02x %s", at(1), eom() ? "eom" : "");
+      break;
+    default:
+      break;
     }
-    break;
-  case MSGCODE_FRAME_START:
-    if (size() >= 2)
-      strMsg.AppendFormat(" initiator:%1x destination:%1x ack:%s %s", initiator(), destination(), ack() ? "high" : "low", eom() ? "eom" : "");
-    break;
-  case MSGCODE_FRAME_DATA:
-    if (size() >= 2)
-      strMsg.AppendFormat(" %02x %s", at(1), eom() ? "eom" : "");
-    break;
-  default:
-    break;
   }
 
   return strMsg;
@@ -237,9 +244,9 @@ void CCECAdapterMessage::push_escaped(uint8_t byte)
     push_back(byte);
 }
 
-CAdapterCommunication::CAdapterCommunication(CLibCEC *controller) :
+CAdapterCommunication::CAdapterCommunication(CCECProcessor *processor) :
     m_port(NULL),
-    m_controller(controller)
+    m_processor(processor)
 {
   m_port = new CSerialPort;
 }
@@ -260,24 +267,24 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
   CLockObject lock(&m_mutex);
   if (!m_port)
   {
-    m_controller->AddLog(CEC_LOG_ERROR, "port is NULL");
+    m_processor->AddLog(CEC_LOG_ERROR, "port is NULL");
     return false;
   }
 
   if (IsOpen())
   {
-    m_controller->AddLog(CEC_LOG_ERROR, "port is already open");
+    m_processor->AddLog(CEC_LOG_ERROR, "port is already open");
   }
 
   if (!m_port->Open(strPort, iBaudRate))
   {
     CStdString strError;
     strError.Format("error opening serial port '%s': %s", strPort, m_port->GetError().c_str());
-    m_controller->AddLog(CEC_LOG_ERROR, strError);
+    m_processor->AddLog(CEC_LOG_ERROR, strError);
     return false;
   }
 
-  m_controller->AddLog(CEC_LOG_DEBUG, "connection opened");
+  m_processor->AddLog(CEC_LOG_DEBUG, "connection opened");
 
   //clear any input bytes
   uint8_t buff[1024];
@@ -286,12 +293,12 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
   if (CreateThread())
   {
     m_startCondition.Wait(&m_mutex);
-    m_controller->AddLog(CEC_LOG_DEBUG, "communication thread started");
+    m_processor->AddLog(CEC_LOG_DEBUG, "communication thread started");
     return true;
   }
   else
   {
-    m_controller->AddLog(CEC_LOG_DEBUG, "could not create a communication thread");
+    m_processor->AddLog(CEC_LOG_DEBUG, "could not create a communication thread");
   }
 
   return false;
@@ -334,7 +341,7 @@ bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
   {
     CStdString strError;
     strError.Format("error reading from serial port: %s", m_port->GetError().c_str());
-    m_controller->AddLog(CEC_LOG_ERROR, strError);
+    m_processor->AddLog(CEC_LOG_ERROR, strError);
     return false;
   }
   else if (iBytesRead > 0)
@@ -366,13 +373,12 @@ void CAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
   {
     CStdString strError;
     strError.Format("error writing to serial port: %s", m_port->GetError().c_str());
-    m_controller->AddLog(CEC_LOG_ERROR, strError);
+    m_processor->AddLog(CEC_LOG_ERROR, strError);
     msg->state = ADAPTER_MESSAGE_STATE_ERROR;
   }
   else
   {
-    m_controller->AddLog(CEC_LOG_DEBUG, "command sent");
-    CCondition::Sleep((uint32_t) msg->size() * 24 /*data*/ + 5 /*start bit (4.5 ms)*/);
+    m_processor->AddLog(CEC_LOG_DEBUG, "command sent");
     msg->state = ADAPTER_MESSAGE_STATE_SENT;
   }
   msg->condition.Signal();
@@ -414,7 +420,7 @@ bool CAdapterCommunication::Read(CCECAdapterMessage &msg, uint32_t iTimeout)
     else if (buf == MSGSTART) //we found a msgstart before msgend, this is not right, remove
     {
       if (msg.size() > 0)
-        m_controller->AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
+        m_processor->AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
       msg.clear();
       bGotStart = true;
     }
@@ -451,14 +457,16 @@ bool CAdapterCommunication::StartBootloader(void)
   if (!IsRunning())
     return bReturn;
 
-  m_controller->AddLog(CEC_LOG_DEBUG, "starting the bootloader");
+  m_processor->AddLog(CEC_LOG_DEBUG, "starting the bootloader");
   CCECAdapterMessage *output = new CCECAdapterMessage;
 
   output->push_back(MSGSTART);
   output->push_escaped(MSGCODE_START_BOOTLOADER);
   output->push_back(MSGEND);
 
-  SendMessageToAdapter(output);
+  CLockObject lock(&output->mutex);
+  if (Write(output))
+    output->condition.Wait(&output->mutex);
   bReturn = output->state == ADAPTER_MESSAGE_STATE_SENT;
   delete output;
 
@@ -471,14 +479,16 @@ bool CAdapterCommunication::PingAdapter(void)
   if (!IsRunning())
     return bReturn;
 
-  m_controller->AddLog(CEC_LOG_DEBUG, "sending ping");
+  m_processor->AddLog(CEC_LOG_DEBUG, "sending ping");
   CCECAdapterMessage *output = new CCECAdapterMessage;
 
   output->push_back(MSGSTART);
   output->push_escaped(MSGCODE_PING);
   output->push_back(MSGEND);
 
-  SendMessageToAdapter(output);
+  CLockObject lock(&output->mutex);
+  if (Write(output))
+    output->condition.Wait(&output->mutex);
   bReturn = output->state == ADAPTER_MESSAGE_STATE_SENT;
   delete output;