win32: serial socket timeouts. bugzid: 654
[deb_libcec.git] / src / lib / adapter / USBCECAdapterCommunication.cpp
index d6f10d91a4a15a7d52e3809d504258a5568937b6..8269d139885028dfe3d92955162667a0c754d2b4 100644 (file)
@@ -42,24 +42,6 @@ using namespace PLATFORM;
 
 #define CEC_ADAPTER_PING_TIMEOUT 15000
 
-void *CUSBCECAdapterProcessor::Process(void)
-{
-  cec_command command;
-  while (!IsStopped())
-  {
-    if (m_inBuffer.Pop(command))
-      m_callback->OnCommandReceived(command);
-    Sleep(5);
-  }
-
-  return NULL;
-}
-
-void CUSBCECAdapterProcessor::AddCommand(cec_command command)
-{
-  m_inBuffer.Push(command);
-}
-
 CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate /* = 38400 */) :
     m_port(NULL),
     m_processor(processor),
@@ -69,7 +51,6 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(CCECProcessor *processo
     m_lastDestination(CECDEVICE_UNKNOWN),
     m_bNextIsEscaped(false),
     m_bGotStart(false),
-    m_messageProcessor(NULL),
     m_bInitialised(false)
 {
   for (unsigned int iPtr = 0; iPtr < 15; iPtr++)
@@ -201,6 +182,7 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32
   {
     CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter failed to pass basic checks");
     delete m_port;
+    m_port = NULL;
     return false;
   }
   else if (bStartListening)
@@ -213,12 +195,15 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32
     else
     {
       delete m_port;
+      m_port = NULL;
       CLibCEC::AddLog(CEC_LOG_ERROR, "could not create a communication thread");
+      return false;
     }
   }
   else
   {
     delete m_port;
+    m_port = NULL;
   }
 
   return true;
@@ -231,9 +216,6 @@ void CUSBCECAdapterCommunication::Close(void)
 
 void *CUSBCECAdapterCommunication::Process(void)
 {
-  m_messageProcessor = new CUSBCECAdapterProcessor(m_callback);
-  m_messageProcessor->CreateThread();
-
   cec_command command;
   command.Clear();
   bool bCommandReceived(false);
@@ -242,13 +224,13 @@ void *CUSBCECAdapterCommunication::Process(void)
   {
     {
       CLockObject lock(m_mutex);
-      ReadFromDevice(50);
+      ReadFromDevice(5);
       bCommandReceived = m_callback && Read(command, 0) && m_bInitialised;
     }
 
     /* push the next command to the callback method if there is one */
     if (!IsStopped() && bCommandReceived)
-      m_messageProcessor->AddCommand(command);
+      m_callback->OnCommandReceived(command);
 
     /* ping the adapter every 15 seconds */
     if (pingTimeout.TimeLeft() == 0)
@@ -258,16 +240,9 @@ void *CUSBCECAdapterCommunication::Process(void)
     }
 
     if (!IsStopped())
-    {
-      Sleep(5);
       WriteNextCommand();
-    }
   }
 
-  /* stop the message processor */
-  m_messageProcessor->StopThread();
-  delete m_messageProcessor;
-
   /* notify all threads that are waiting on messages to be sent */
   CCECAdapterMessage *msg(NULL);
   while (m_outBuffer.Pop(msg))
@@ -285,6 +260,7 @@ void *CUSBCECAdapterCommunication::Process(void)
     m_port = NULL;
   }
 
+  m_rcvCondition.Broadcast();
   return NULL;
 }
 
@@ -306,6 +282,7 @@ cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &
   output->retryTimeout = iRetryLineTimeout;
   output->tries = 0;
 
+  if (data.destination < 15)
   {
     CLockObject lock(m_mutex);
     m_bWaitingForAck[data.destination] = true;
@@ -435,10 +412,13 @@ bool CUSBCECAdapterCommunication::ParseMessage(const CCECAdapterMessage &msg)
       if (m_currentframe.ack == 0x1)
       {
         m_lastDestination    = m_currentframe.destination;
-        if (!m_bWaitingForAck[m_currentframe.destination])
-          m_processor->HandlePoll(m_currentframe.initiator, m_currentframe.destination);
-        else
-          m_bWaitingForAck[m_currentframe.destination] = false;
+        if (m_currentframe.destination < 15)
+        {
+          if (!m_bWaitingForAck[m_currentframe.destination])
+            m_processor->HandlePoll(m_currentframe.initiator, m_currentframe.destination);
+          else
+            m_bWaitingForAck[m_currentframe.destination] = false;
+        }
       }
     }
     break;
@@ -818,9 +798,9 @@ bool CUSBCECAdapterCommunication::WaitForAck(CCECAdapterMessage &message)
 
     if (msg.Message() == MSGCODE_FRAME_START && msg.IsACK())
     {
-      if (m_bWaitingForAck[msg.Initiator()])
+      if (msg.Initiator() < 15 && m_bWaitingForAck[msg.Initiator()])
         m_bWaitingForAck[msg.Initiator()] = false;
-      else
+      else if (msg.Initiator() < 15)
       {
         m_processor->HandlePoll(msg.Initiator(), msg.Destination());
         m_lastDestination = msg.Initiator();
@@ -1015,12 +995,14 @@ bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, C
     Write(output);
 
   bool bWriteOk = output->state == (output->expectControllerAck ? ADAPTER_MESSAGE_STATE_SENT_ACKED : ADAPTER_MESSAGE_STATE_SENT);
+  cec_adapter_messagecode reply = output->reply;
+  delete output;
+
   if (!bWriteOk)
   {
     CLibCEC::AddLog(CEC_LOG_ERROR, "'%s' failed", CCECAdapterMessage::ToString(msgCode));
-    delete output;
 
-    if (!bIsRetry && output->reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
+    if (!bIsRetry && reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
     {
       CLibCEC::AddLog(CEC_LOG_DEBUG, "setting controlled mode and retrying");
       if (SetControlledMode(true))
@@ -1029,7 +1011,6 @@ bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, C
     return false;
   }
 
-  delete output;
   return true;
 }
 
@@ -1045,7 +1026,6 @@ cec_datapacket CUSBCECAdapterCommunication::GetSetting(cec_adapter_messagecode m
     return retVal;
   }
 
-  Sleep(250); // TODO ReadFromDevice() isn't waiting for the timeout to pass on win32
   ReadFromDevice(CEC_DEFAULT_TRANSMIT_WAIT, iResponseLength + 3 /* start + msgcode + iResponseLength + end */);
   CCECAdapterMessage input;
   if (Read(input, 0))