added GetAdapterProductId()+GetAdapterVendorId()/cec_get_adapter_product_id()+cec_get...
[deb_libcec.git] / src / lib / adapter / Pulse-Eight / USBCECAdapterCommunication.cpp
index 70e45ac6c30e00e06987cf9c001f67cf55c68028..7fa78f73638b96eff4e9ace948a258f57247affd 100644 (file)
@@ -36,6 +36,7 @@
 #include "USBCECAdapterCommands.h"
 #include "USBCECAdapterMessageQueue.h"
 #include "USBCECAdapterMessage.h"
+#include "USBCECAdapterDetection.h"
 #include "lib/platform/sockets/serialport.h"
 #include "lib/platform/util/timeutils.h"
 #include "lib/platform/util/util.h"
@@ -59,6 +60,7 @@ using namespace PLATFORM;
 #define CEC_LATEST_ADAPTER_FW_DATE    0x501a4b0c
 
 #define CEC_FW_DATE_EXTENDED_RESPONSE 0x501a4b0c
+#define CEC_FW_DATE_DESCRIPTOR2       0x5045dbf5
 
 #define LIB_CEC m_callback->GetLib()
 
@@ -234,24 +236,33 @@ void CUSBCECAdapterCommunication::Close(void)
     m_port->Close();
 }
 
-cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool UNUSED(bIsReply))
+cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply)
 {
   cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN);
   if (!IsRunning())
     return retVal;
 
   CCECAdapterMessage *output = new CCECAdapterMessage(data, iLineTimeout);
+  output->bFireAndForget = bIsReply;
 
   /* mark as waiting for an ack from the destination */
   MarkAsWaiting(data.destination);
 
   /* send the message */
-  bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0;
-  if (bRetry)
-    Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
-  retVal = output->state;
+  if (bIsReply)
+  {
+    retVal = m_adapterMessageQueue->Write(output) ?
+        ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT : ADAPTER_MESSAGE_STATE_ERROR;
+  }
+  else
+  {
+    bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0;
+    if (bRetry)
+      Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
+    retVal = output->state;
 
-  delete output;
+    delete output;
+  }
   return retVal;
 }
 
@@ -375,7 +386,9 @@ bool CUSBCECAdapterCommunication::WriteToDevice(CCECAdapterMessage *message)
     return false;
   }
 
+#ifdef CEC_DEBUGGING
   LIB_CEC->AddLog(CEC_LOG_DEBUG, "command '%s' sent", message->IsTranmission() ? "CEC transmission" : CCECAdapterMessage::ToString(message->Message()));
+#endif
   message->state = ADAPTER_MESSAGE_STATE_SENT;
   return true;
 }
@@ -393,7 +406,11 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize
     if (!IsOpen())
       return false;
 
-    iBytesRead = m_port->Read(buff, sizeof(uint8_t) * iSize, iTimeout);
+    do {
+      /* retry Read() if it was interrupted */
+      iBytesRead = m_port->Read(buff, sizeof(uint8_t) * iSize, iTimeout);
+    } while(m_port->GetErrorNumber() == EINTR);
+
 
     if (m_port->GetErrorNumber())
     {
@@ -482,8 +499,14 @@ bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = CEC_DEFA
   else
     bReturn = true;
 
-  /* try to read the build date */
-  m_commands->RequestBuildDate();
+  if (m_commands->GetFirmwareVersion() >= 2)
+  {
+    /* try to read the build date */
+    m_commands->RequestBuildDate();
+
+    /* try to read the adapter type */
+    m_commands->RequestAdapterType();
+  }
 
   SetInitialised(bReturn);
   return bReturn;
@@ -570,6 +593,17 @@ uint32_t CUSBCECAdapterCommunication::GetFirmwareBuildDate(void)
   return iBuildDate;
 }
 
+cec_adapter_type CUSBCECAdapterCommunication::GetAdapterType(void)
+{
+  cec_adapter_type type(ADAPTERTYPE_UNKNOWN);
+  if (m_commands)
+    type = (cec_adapter_type)m_commands->GetPersistedAdapterType();
+  if (type == ADAPTERTYPE_UNKNOWN && IsOpen())
+    type = (cec_adapter_type)m_commands->RequestAdapterType();
+
+  return type;
+}
+
 bool CUSBCECAdapterCommunication::ProvidesExtendedResponse(void)
 {
   uint32_t iBuildDate(0);
@@ -579,6 +613,20 @@ bool CUSBCECAdapterCommunication::ProvidesExtendedResponse(void)
   return iBuildDate >= CEC_FW_DATE_EXTENDED_RESPONSE;
 }
 
+uint16_t CUSBCECAdapterCommunication::GetAdapterVendorId(void) const
+{
+  return CEC_VID;
+}
+
+uint16_t CUSBCECAdapterCommunication::GetAdapterProductId(void) const
+{
+  uint32_t iBuildDate(0);
+  if (m_commands)
+    iBuildDate = m_commands->GetPersistedBuildDate();
+
+  return iBuildDate >= CEC_FW_DATE_DESCRIPTOR2 ? CEC_PID2 : CEC_PID;
+}
+
 bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void)
 {
   return GetFirmwareBuildDate() >= CEC_LATEST_ADAPTER_FW_DATE &&