cec: clean ups and only include what we need from lib/platform.
[deb_libcec.git] / src / lib / adapter / AdapterCommunication.cpp
index 15b6851ae5abcf843d00d516626095ad85ae7ee5..ff69a7f4a73f2aeb6a10cf43bb9a888e21190330 100644 (file)
 #include "AdapterCommunication.h"
 
 #include "AdapterMessage.h"
-#include "CECProcessor.h"
-#include "platform/serialport/serialport.h"
+#include "../CECProcessor.h"
+#include "../platform/sockets/serialport.h"
+#include "../platform/util/timeutils.h"
+#include "../LibCEC.h"
 
 using namespace std;
 using namespace CEC;
@@ -69,13 +71,13 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
 
   if (!m_port)
   {
-    m_processor->AddLog(CEC_LOG_ERROR, "port is NULL");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "port is NULL");
     return false;
   }
 
   if (IsOpen())
   {
-    m_processor->AddLog(CEC_LOG_ERROR, "port is already open");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "port is already open");
     return true;
   }
 
@@ -93,24 +95,28 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
 
   if (!bConnected)
   {
-    m_processor->AddLog(CEC_LOG_ERROR, strError);
+    CLibCEC::AddLog(CEC_LOG_ERROR, strError);
     return false;
   }
 
-  m_processor->AddLog(CEC_LOG_DEBUG, "connection opened");
+  CLibCEC::AddLog(CEC_LOG_DEBUG, "connection opened, clearing any previous input and waiting for active transmissions to end before starting");
 
   //clear any input bytes
-  uint8_t buff[1];
-  while (m_port->Read(buff, 1, 5) == 1) {}
+  uint8_t buff[1024];
+  while (m_port->Read(buff, 1024, 100) > 0)
+  {
+    CLibCEC::AddLog(CEC_LOG_DEBUG, "data received, clearing it");
+    Sleep(250);
+  }
 
   if (CreateThread())
   {
-    m_processor->AddLog(CEC_LOG_DEBUG, "communication thread started");
+    CLibCEC::AddLog(CEC_LOG_DEBUG, "communication thread started");
     return true;
   }
   else
   {
-    m_processor->AddLog(CEC_LOG_ERROR, "could not create a communication thread");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "could not create a communication thread");
   }
 
   return false;
@@ -150,12 +156,11 @@ bool CAdapterCommunication::Write(CCECAdapterMessage *data)
 
   if (data->state != ADAPTER_MESSAGE_STATE_SENT)
   {
-    m_processor->AddLog(CEC_LOG_ERROR, "command was not sent");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "command was not sent");
   }
-
-  if (data->expectControllerAck)
+  else if (data->expectControllerAck)
   {
-    bReturn = WaitForTransmitSucceeded(data);
+    bReturn = WaitForAck(*data);
     if (bReturn)
     {
       if (data->isTransmission)
@@ -164,7 +169,7 @@ bool CAdapterCommunication::Write(CCECAdapterMessage *data)
     else
     {
       data->state = ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED;
-      m_processor->AddLog(CEC_LOG_DEBUG, "did not receive ack");
+      CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack");
     }
   }
   else
@@ -204,7 +209,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_processor->AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
+        CLibCEC::AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
       msg.Clear();
       bGotStart = true;
     }
@@ -230,9 +235,11 @@ bool CAdapterCommunication::Read(CCECAdapterMessage &msg, uint32_t iTimeout)
   return bGotFullMessage;
 }
 
-std::string CAdapterCommunication::GetError(void) const
+CStdString CAdapterCommunication::GetError(void) const
 {
-  return m_port->GetError();
+  CStdString strError;
+  strError = m_port->GetError();
+  return strError;
 }
 
 bool CAdapterCommunication::StartBootloader(void)
@@ -241,7 +248,7 @@ bool CAdapterCommunication::StartBootloader(void)
   if (!IsRunning())
     return bReturn;
 
-  m_processor->AddLog(CEC_LOG_DEBUG, "starting the bootloader");
+  CLibCEC::AddLog(CEC_LOG_DEBUG, "starting the bootloader");
   CCECAdapterMessage *output = new CCECAdapterMessage;
 
   output->PushBack(MSGSTART);
@@ -251,7 +258,7 @@ bool CAdapterCommunication::StartBootloader(void)
   output->expectControllerAck = false;
 
   if ((bReturn = Write(output)) == false)
-    m_processor->AddLog(CEC_LOG_ERROR, "could not start the bootloader");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "could not start the bootloader");
   delete output;
 
   return bReturn;
@@ -263,7 +270,7 @@ bool CAdapterCommunication::PingAdapter(void)
   if (!IsRunning())
     return bReturn;
 
-  m_processor->AddLog(CEC_LOG_DEBUG, "sending ping");
+  CLibCEC::AddLog(CEC_LOG_DEBUG, "sending ping");
   CCECAdapterMessage *output = new CCECAdapterMessage;
 
   output->PushBack(MSGSTART);
@@ -272,7 +279,7 @@ bool CAdapterCommunication::PingAdapter(void)
   output->isTransmission = false;
 
   if ((bReturn = Write(output)) == false)
-    m_processor->AddLog(CEC_LOG_ERROR, "could not ping the adapter");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "could not ping the adapter");
   delete output;
 
   return bReturn;
@@ -286,7 +293,7 @@ uint16_t CAdapterCommunication::GetFirmwareVersion(void)
 
   if (iReturn == CEC_FW_VERSION_UNKNOWN)
   {
-    m_processor->AddLog(CEC_LOG_DEBUG, "requesting the firmware version");
+    CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting the firmware version");
     CCECAdapterMessage *output = new CCECAdapterMessage;
 
     output->PushBack(MSGSTART);
@@ -300,7 +307,7 @@ uint16_t CAdapterCommunication::GetFirmwareVersion(void)
 
     CCECAdapterMessage input;
     if (!Read(input, CEC_DEFAULT_TRANSMIT_WAIT) || input.Message() != MSGCODE_FIRMWARE_VERSION || input.Size() != 3)
-      m_processor->AddLog(CEC_LOG_ERROR, "no or invalid firmware version");
+      CLibCEC::AddLog(CEC_LOG_ERROR, "no or invalid firmware version (size = %d, message = %d)", input.Size(), input.Message());
     else
     {
       m_iFirmwareVersion = (input[1] << 8 | input[2]);
@@ -326,7 +333,7 @@ bool CAdapterCommunication::SetLineTimeout(uint8_t iTimeout)
     output->isTransmission = false;
 
     if ((bReturn = Write(output)) == false)
-      m_processor->AddLog(CEC_LOG_ERROR, "could not set the idletime");
+      CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the idletime");
     delete output;
   }
 
@@ -338,7 +345,7 @@ bool CAdapterCommunication::SetAckMask(uint16_t iMask)
   bool bReturn(false);
   CStdString strLog;
   strLog.Format("setting ackmask to %2x", iMask);
-  m_processor->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+  CLibCEC::AddLog(CEC_LOG_DEBUG, strLog.c_str());
 
   CCECAdapterMessage *output = new CCECAdapterMessage;
 
@@ -350,7 +357,7 @@ bool CAdapterCommunication::SetAckMask(uint16_t iMask)
   output->isTransmission = false;
 
   if ((bReturn = Write(output)) == false)
-    m_processor->AddLog(CEC_LOG_ERROR, "could not set the ackmask");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the ackmask");
   delete output;
 
   return bReturn;
@@ -361,20 +368,23 @@ bool CAdapterCommunication::IsOpen(void)
   return !IsStopped() && m_port->IsOpen() && IsRunning();
 }
 
-bool CAdapterCommunication::WaitForTransmitSucceeded(CCECAdapterMessage *message)
+bool CAdapterCommunication::WaitForAck(CCECAdapterMessage &message)
 {
   bool bError(false);
   bool bTransmitSucceeded(false);
-  uint8_t iPacketsLeft(message->Size() / 4);
+  uint8_t iPacketsLeft(message.Size() / 4);
 
   int64_t iNow = GetTimeMs();
-  int64_t iTargetTime = iNow + message->transmit_timeout;
+  int64_t iTargetTime = iNow + message.transmit_timeout;
 
-  while (!bTransmitSucceeded && !bError && (message->transmit_timeout == 0 || iNow < iTargetTime))
+  while (!bTransmitSucceeded && !bError && (message.transmit_timeout == 0 || iNow < iTargetTime))
   {
     CCECAdapterMessage msg;
+    int32_t iWait = (int32_t)(iTargetTime - iNow);
+    if (iWait <= 5 || message.transmit_timeout <= 5)
+      iWait = CEC_DEFAULT_TRANSMIT_WAIT;
 
-    if (!Read(msg, message->transmit_timeout > 0 ? (int32_t)(iTargetTime - iNow) : 1000))
+    if (!Read(msg, iWait))
     {
       iNow = GetTimeMs();
       continue;
@@ -397,25 +407,25 @@ bool CAdapterCommunication::WaitForTransmitSucceeded(CCECAdapterMessage *message
     bError = msg.IsError();
     if (bError)
     {
-      message->reply = msg.Message();
-      m_processor->AddLog(CEC_LOG_DEBUG, msg.ToString());
+      message.reply = msg.Message();
+      CLibCEC::AddLog(CEC_LOG_DEBUG, msg.ToString());
     }
     else
     {
       switch(msg.Message())
       {
       case MSGCODE_COMMAND_ACCEPTED:
-        m_processor->AddLog(CEC_LOG_DEBUG, msg.ToString());
+        CLibCEC::AddLog(CEC_LOG_DEBUG, msg.ToString());
         if (iPacketsLeft > 0)
           iPacketsLeft--;
-        if (!message->isTransmission && iPacketsLeft == 0)
+        if (!message.isTransmission && iPacketsLeft == 0)
           bTransmitSucceeded = true;
         break;
       case MSGCODE_TRANSMIT_SUCCEEDED:
-        m_processor->AddLog(CEC_LOG_DEBUG, msg.ToString());
+        CLibCEC::AddLog(CEC_LOG_DEBUG, msg.ToString());
         bTransmitSucceeded = (iPacketsLeft == 0);
         bError = !bTransmitSucceeded;
-        message->reply = MSGCODE_TRANSMIT_SUCCEEDED;
+        message.reply = MSGCODE_TRANSMIT_SUCCEEDED;
         break;
       default:
         // ignore other data while waiting
@@ -451,7 +461,7 @@ bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
   {
     CStdString strError;
     strError.Format("error reading from serial port: %s", m_port->GetError().c_str());
-    m_processor->AddLog(CEC_LOG_ERROR, strError);
+    CLibCEC::AddLog(CEC_LOG_ERROR, strError);
     return false;
   }
   else if (iBytesRead > 0)
@@ -468,12 +478,12 @@ void CAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
   {
     CStdString strError;
     strError.Format("error writing to serial port: %s", m_port->GetError().c_str());
-    m_processor->AddLog(CEC_LOG_ERROR, strError);
+    CLibCEC::AddLog(CEC_LOG_ERROR, strError);
     msg->state = ADAPTER_MESSAGE_STATE_ERROR;
   }
   else
   {
-    m_processor->AddLog(CEC_LOG_DEBUG, "command sent");
+    CLibCEC::AddLog(CEC_LOG_DEBUG, "command sent");
     msg->state = ADAPTER_MESSAGE_STATE_SENT;
   }
   msg->condition.Signal();