cec: moved all adapter related code to src/lib/adapter, camelcased CAdapterMessage...
[deb_libcec.git] / src / lib / adapter / AdapterCommunication.cpp
similarity index 54%
rename from src/lib/AdapterCommunication.cpp
rename to src/lib/adapter/AdapterCommunication.cpp
index faa15aa27100e2f1dcc32e9b86aafd047c999b53..4a136ab113f4bef0a8e1fcdd83b19506d49f7eb1 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "AdapterCommunication.h"
 
+#include "AdapterMessage.h"
 #include "CECProcessor.h"
 #include "platform/serialport/serialport.h"
 
@@ -39,210 +40,6 @@ using namespace std;
 using namespace CEC;
 using namespace PLATFORM;
 
-CCECAdapterMessage::CCECAdapterMessage(const cec_command &command)
-{
-  clear();
-
-  //set ack polarity to high when transmitting to the broadcast address
-  //set ack polarity low when transmitting to any other address
-  push_back(MSGSTART);
-  push_escaped(MSGCODE_TRANSMIT_ACK_POLARITY);
-  if (command.destination == CECDEVICE_BROADCAST)
-    push_escaped(CEC_TRUE);
-  else
-    push_escaped(CEC_FALSE);
-  push_back(MSGEND);
-
-  // add source and destination
-  push_back(MSGSTART);
-  push_escaped(command.opcode_set == 0 ? (uint8_t)MSGCODE_TRANSMIT_EOM : (uint8_t)MSGCODE_TRANSMIT);
-  push_back(((uint8_t)command.initiator << 4) + (uint8_t)command.destination);
-  push_back(MSGEND);
-
-  // add opcode
-  if (command.opcode_set == 1)
-  {
-    push_back(MSGSTART);
-    push_escaped(command.parameters.IsEmpty() ? (uint8_t)MSGCODE_TRANSMIT_EOM : (uint8_t)MSGCODE_TRANSMIT);
-    push_back((uint8_t) command.opcode);
-    push_back(MSGEND);
-
-    // add parameters
-    for (int8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
-    {
-      push_back(MSGSTART);
-
-      if (iPtr == command.parameters.size - 1)
-        push_escaped( MSGCODE_TRANSMIT_EOM);
-      else
-        push_escaped(MSGCODE_TRANSMIT);
-
-      push_escaped(command.parameters[iPtr]);
-
-      push_back(MSGEND);
-    }
-  }
-
-  // set timeout
-  transmit_timeout = command.transmit_timeout;
-}
-
-CCECAdapterMessage &CCECAdapterMessage::operator =(const CCECAdapterMessage &msg)
-{
-  packet = msg.packet;
-  state  = msg.state;
-  return *this;
-}
-
-CStdString CCECAdapterMessage::MessageCodeAsString(void) const
-{
-  CStdString strMsg;
-  switch (message())
-  {
-  case MSGCODE_NOTHING:
-    strMsg = "NOTHING";
-    break;
-  case MSGCODE_PING:
-    strMsg = "PING";
-    break;
-  case MSGCODE_TIMEOUT_ERROR:
-    strMsg = "TIMEOUT";
-    break;
-  case MSGCODE_HIGH_ERROR:
-    strMsg = "HIGH_ERROR";
-    break;
-  case MSGCODE_LOW_ERROR:
-    strMsg = "LOW_ERROR";
-    break;
-  case MSGCODE_FRAME_START:
-    strMsg = "FRAME_START";
-    break;
-  case MSGCODE_FRAME_DATA:
-    strMsg = "FRAME_DATA";
-    break;
-  case MSGCODE_RECEIVE_FAILED:
-    strMsg = "RECEIVE_FAILED";
-    break;
-  case MSGCODE_COMMAND_ACCEPTED:
-    strMsg = "COMMAND_ACCEPTED";
-    break;
-  case MSGCODE_COMMAND_REJECTED:
-    strMsg = "COMMAND_REJECTED";
-    break;
-  case MSGCODE_SET_ACK_MASK:
-    strMsg = "SET_ACK_MASK";
-    break;
-  case MSGCODE_TRANSMIT:
-    strMsg = "TRANSMIT";
-    break;
-  case MSGCODE_TRANSMIT_EOM:
-    strMsg = "TRANSMIT_EOM";
-    break;
-  case MSGCODE_TRANSMIT_IDLETIME:
-    strMsg = "TRANSMIT_IDLETIME";
-    break;
-  case MSGCODE_TRANSMIT_ACK_POLARITY:
-    strMsg = "TRANSMIT_ACK_POLARITY";
-    break;
-  case MSGCODE_TRANSMIT_LINE_TIMEOUT:
-    strMsg = "TRANSMIT_LINE_TIMEOUT";
-    break;
-  case MSGCODE_TRANSMIT_SUCCEEDED:
-    strMsg = "TRANSMIT_SUCCEEDED";
-    break;
-  case MSGCODE_TRANSMIT_FAILED_LINE:
-    strMsg = "TRANSMIT_FAILED_LINE";
-    break;
-  case MSGCODE_TRANSMIT_FAILED_ACK:
-    strMsg = "TRANSMIT_FAILED_ACK";
-    break;
-  case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
-    strMsg = "TRANSMIT_FAILED_TIMEOUT_DATA";
-    break;
-  case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
-    strMsg = "TRANSMIT_FAILED_TIMEOUT_LINE";
-    break;
-  case MSGCODE_FIRMWARE_VERSION:
-    strMsg = "FIRMWARE_VERSION";
-    break;
-  case MSGCODE_START_BOOTLOADER:
-    strMsg = "START_BOOTLOADER";
-    break;
-  case MSGCODE_FRAME_EOM:
-    strMsg = "FRAME_EOM";
-    break;
-  case MSGCODE_FRAME_ACK:
-    strMsg = "FRAME_ACK";
-    break;
-  }
-
-  return strMsg;
-}
-
-CStdString CCECAdapterMessage::ToString(void) const
-{
-  CStdString strMsg;
-  if (size() == 0)
-  {
-    strMsg = "empty message";
-  }
-  else
-  {
-    strMsg = MessageCodeAsString();
-
-    switch (message())
-    {
-    case MSGCODE_TIMEOUT_ERROR:
-    case MSGCODE_HIGH_ERROR:
-    case MSGCODE_LOW_ERROR:
-      {
-        uint32_t 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:%u", 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;
-    }
-  }
-
-  return strMsg;
-}
-
-bool CCECAdapterMessage::is_error(void) const
-{
-  cec_adapter_messagecode code = message();
-  return (code == MSGCODE_HIGH_ERROR ||
-    code == MSGCODE_LOW_ERROR ||
-    code == MSGCODE_RECEIVE_FAILED ||
-    code == MSGCODE_COMMAND_REJECTED ||
-    code == MSGCODE_TRANSMIT_LINE_TIMEOUT ||
-    code == MSGCODE_TRANSMIT_FAILED_LINE ||
-    code == MSGCODE_TRANSMIT_FAILED_ACK ||
-    code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA ||
-    code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE);
-}
-
-void CCECAdapterMessage::push_escaped(uint8_t byte)
-{
-  if (byte >= MSGESC)
-  {
-    push_back(MSGESC);
-    push_back(byte - ESCOFFSET);
-  }
-  else
-    push_back(byte);
-}
-
 CAdapterCommunication::CAdapterCommunication(CCECProcessor *processor) :
     m_port(NULL),
     m_processor(processor),
@@ -307,13 +104,12 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
 
   if (CreateThread())
   {
-    m_startCondition.Wait(m_mutex);
     m_processor->AddLog(CEC_LOG_DEBUG, "communication thread started");
     return true;
   }
   else
   {
-    m_processor->AddLog(CEC_LOG_DEBUG, "could not create a communication thread");
+    m_processor->AddLog(CEC_LOG_ERROR, "could not create a communication thread");
   }
 
   return false;
@@ -322,18 +118,12 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
 void CAdapterCommunication::Close(void)
 {
   CLockObject lock(m_mutex);
-  m_startCondition.Broadcast();
   m_rcvCondition.Broadcast();
   StopThread();
 }
 
 void *CAdapterCommunication::Process(void)
 {
-  {
-    CLockObject lock(m_mutex);
-    m_startCondition.Signal();
-  }
-
   while (!IsStopped())
   {
     ReadFromDevice(50);
@@ -341,68 +131,13 @@ void *CAdapterCommunication::Process(void)
     WriteNextCommand();
   }
 
-  CCECAdapterMessage *msg;
+  CCECAdapterMessage *msg(NULL);
   if (m_outBuffer.Pop(msg))
     msg->condition.Broadcast();
 
   return NULL;
 }
 
-bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
-{
-  int32_t iBytesRead;
-  uint8_t buff[1024];
-  if (!m_port)
-    return false;
-
-  iBytesRead = m_port->Read(buff, sizeof(buff), iTimeout);
-  if (iBytesRead < 0 || iBytesRead > 256)
-  {
-    CStdString strError;
-    strError.Format("error reading from serial port: %s", m_port->GetError().c_str());
-    m_processor->AddLog(CEC_LOG_ERROR, strError);
-    return false;
-  }
-  else if (iBytesRead > 0)
-    AddData(buff, (uint8_t) iBytesRead);
-
-  return iBytesRead > 0;
-}
-
-void CAdapterCommunication::AddData(uint8_t *data, uint8_t iLen)
-{
-  CLockObject lock(m_mutex);
-  for (uint8_t iPtr = 0; iPtr < iLen; iPtr++)
-    m_inBuffer.Push(data[iPtr]);
-
-  m_rcvCondition.Signal();
-}
-
-void CAdapterCommunication::WriteNextCommand(void)
-{
-  CCECAdapterMessage *msg;
-  if (m_outBuffer.Pop(msg))
-    SendMessageToAdapter(msg);
-}
-
-void CAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
-{
-  CLockObject lock(msg->mutex);
-  if (m_port->Write(msg->packet.data, msg->size()) != (int32_t) msg->size())
-  {
-    CStdString strError;
-    strError.Format("error writing to serial port: %s", m_port->GetError().c_str());
-    m_processor->AddLog(CEC_LOG_ERROR, strError);
-    msg->state = ADAPTER_MESSAGE_STATE_ERROR;
-  }
-  else
-  {
-    m_processor->AddLog(CEC_LOG_DEBUG, "command sent");
-    msg->state = ADAPTER_MESSAGE_STATE_SENT;
-  }
-  msg->condition.Signal();
-}
-
 bool CAdapterCommunication::Write(CCECAdapterMessage *data)
 {
   data->state = ADAPTER_MESSAGE_STATE_WAITING;
@@ -414,7 +149,7 @@ bool CAdapterCommunication::Read(CCECAdapterMessage &msg, uint32_t iTimeout)
 {
   CLockObject lock(m_mutex);
 
-  msg.clear();
+  msg.Clear();
   uint64_t iNow = GetTimeMs();
   uint64_t iTarget = iNow + iTimeout;
   bool bGotFullMessage(false);
@@ -438,9 +173,9 @@ 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)
+      if (msg.Size() > 0)
         m_processor->AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
-      msg.clear();
+      msg.Clear();
       bGotStart = true;
     }
 
@@ -450,13 +185,13 @@ bool CAdapterCommunication::Read(CCECAdapterMessage &msg, uint32_t iTimeout)
     }
     else if (bNextIsEscaped)
     {
-      msg.push_back(buf + (uint8_t)ESCOFFSET);
+      msg.PushBack(buf + (uint8_t)ESCOFFSET);
       bNextIsEscaped = false;
     }
     else if (buf == MSGESC)
       bNextIsEscaped = true;
     else
-      msg.push_back(buf);
+      msg.PushBack(buf);
   }
 
   if (bGotFullMessage)
@@ -479,9 +214,9 @@ bool CAdapterCommunication::StartBootloader(void)
   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);
+  output->PushBack(MSGSTART);
+  output->PushEscaped(MSGCODE_START_BOOTLOADER);
+  output->PushBack(MSGEND);
 
   CLockObject lock(output->mutex);
   if (Write(output))
@@ -501,9 +236,9 @@ bool CAdapterCommunication::PingAdapter(void)
   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);
+  output->PushBack(MSGSTART);
+  output->PushEscaped(MSGCODE_PING);
+  output->PushBack(MSGEND);
 
   CLockObject lock(output->mutex);
   if (Write(output))
@@ -522,10 +257,10 @@ bool CAdapterCommunication::SetLineTimeout(uint8_t iTimeout)
   {
     CCECAdapterMessage *output = new CCECAdapterMessage;
 
-    output->push_back(MSGSTART);
-    output->push_escaped(MSGCODE_TRANSMIT_IDLETIME);
-    output->push_escaped(iTimeout);
-    output->push_back(MSGEND);
+    output->PushBack(MSGSTART);
+    output->PushEscaped(MSGCODE_TRANSMIT_IDLETIME);
+    output->PushEscaped(iTimeout);
+    output->PushBack(MSGEND);
 
     if ((bReturn = Write(output)) == false)
       m_processor->AddLog(CEC_LOG_ERROR, "could not set the idletime");
@@ -539,3 +274,58 @@ bool CAdapterCommunication::IsOpen(void)
 {
   return !IsStopped() && m_port->IsOpen() && IsRunning();
 }
+
+void CAdapterCommunication::AddData(uint8_t *data, uint8_t iLen)
+{
+  CLockObject lock(m_mutex);
+  for (uint8_t iPtr = 0; iPtr < iLen; iPtr++)
+    m_inBuffer.Push(data[iPtr]);
+
+  m_rcvCondition.Signal();
+}
+
+bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
+{
+  int32_t iBytesRead;
+  uint8_t buff[1024];
+  if (!m_port)
+    return false;
+
+  iBytesRead = m_port->Read(buff, sizeof(buff), iTimeout);
+  if (iBytesRead < 0 || iBytesRead > 256)
+  {
+    CStdString strError;
+    strError.Format("error reading from serial port: %s", m_port->GetError().c_str());
+    m_processor->AddLog(CEC_LOG_ERROR, strError);
+    return false;
+  }
+  else if (iBytesRead > 0)
+    AddData(buff, (uint8_t) iBytesRead);
+
+  return iBytesRead > 0;
+}
+
+void CAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
+{
+  CLockObject lock(msg->mutex);
+  if (m_port->Write(msg->packet.data, msg->Size()) != (int32_t) msg->Size())
+  {
+    CStdString strError;
+    strError.Format("error writing to serial port: %s", m_port->GetError().c_str());
+    m_processor->AddLog(CEC_LOG_ERROR, strError);
+    msg->state = ADAPTER_MESSAGE_STATE_ERROR;
+  }
+  else
+  {
+    m_processor->AddLog(CEC_LOG_DEBUG, "command sent");
+    msg->state = ADAPTER_MESSAGE_STATE_SENT;
+  }
+  msg->condition.Signal();
+}
+
+void CAdapterCommunication::WriteNextCommand(void)
+{
+  CCECAdapterMessage *msg(NULL);
+  if (m_outBuffer.Pop(msg))
+    SendMessageToAdapter(msg);
+}