changed 'couldn't change the ackmask: the connection is closed' into a debug message
[deb_libcec.git] / src / lib / adapter / USBCECAdapterCommunication.cpp
index 33eb26080081f467f572450db4f0860a511fc0ae..b3f0f7da7ba3209806b402c2e6e839d4c0b2648f 100644 (file)
@@ -36,6 +36,9 @@
 #include "../platform/sockets/serialport.h"
 #include "../platform/util/timeutils.h"
 #include "../platform/util/util.h"
+#include "../platform/util/edid.h"
+#include "../platform/adl/adl-edid.h"
+#include "../platform/nvidia/nv-edid.h"
 #include "../LibCEC.h"
 #include "../CECProcessor.h"
 
@@ -66,6 +69,7 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCa
   for (unsigned int iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++)
     m_bWaitingForAck[iPtr] = false;
   m_port = new CSerialPort(strPort, iBaudRate);
+  m_commands = new CUSBCECAdapterCommands(this);
 }
 
 CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void)
@@ -76,6 +80,13 @@ CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void)
   DELETE_AND_NULL(m_port);
 }
 
+void CUSBCECAdapterCommunication::ResetMessageQueue(void)
+{
+  DELETE_AND_NULL(m_adapterMessageQueue);
+  m_adapterMessageQueue = new CCECAdapterMessageQueue(this);
+  m_adapterMessageQueue->CreateThread();
+}
+
 bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */, bool bSkipChecks /* = false */, bool bStartListening /* = true */)
 {
   bool bConnectionOpened(false);
@@ -96,15 +107,7 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN
       return true;
     }
 
-    /* adapter commands */
-    if (!m_commands)
-      m_commands = new CUSBCECAdapterCommands(this);
-
-    if (!m_adapterMessageQueue)
-    {
-      m_adapterMessageQueue = new CCECAdapterMessageQueue(this);
-      m_adapterMessageQueue->CreateThread();
-    }
+    ResetMessageQueue();
 
     /* try to open the connection */
     CStdString strError;
@@ -145,6 +148,9 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN
     ClearInputBytes();
   }
 
+  // always start by setting the ackmask to 0, to clear previous values
+  SetAckMask(0);
+
   if (!CreateThread())
   {
     bConnectionOpened = false;
@@ -493,21 +499,26 @@ bool CUSBCECAdapterCommunication::StartBootloader(void)
 
 bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask)
 {
-  if (m_iAckMask == iMask)
-    return true;
+  {
+    CLockObject lock(m_mutex);
+    if (m_iAckMask == iMask)
+      return true;
+  }
 
   if (IsOpen() && m_commands->SetAckMask(iMask))
   {
+    CLockObject lock(m_mutex);
     m_iAckMask = iMask;
     return true;
   }
 
-  LIB_CEC->AddLog(CEC_LOG_ERROR, "couldn't change the ackmask: the connection is closed");
+  LIB_CEC->AddLog(CEC_LOG_DEBUG, "couldn't change the ackmask: the connection is closed");
   return false;
 }
 
 uint16_t CUSBCECAdapterCommunication::GetAckMask(void)
 {
+  CLockObject lock(m_mutex);
   return m_iAckMask;
 }
 
@@ -518,12 +529,12 @@ bool CUSBCECAdapterCommunication::PingAdapter(void)
 
 uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void)
 {
-  return IsOpen() ? m_commands->GetFirmwareVersion() : CEC_FW_VERSION_UNKNOWN;
+  return m_commands ? m_commands->GetFirmwareVersion() : CEC_FW_VERSION_UNKNOWN;
 }
 
 uint32_t CUSBCECAdapterCommunication::GetFirmwareBuildDate(void)
 {
-  return IsOpen() ? m_commands->RequestBuildDate() : 0;
+  return IsOpen() ? m_commands->RequestBuildDate() : m_commands ? m_commands->GetPersistedBuildDate() : 0;
 }
 
 bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void)
@@ -552,6 +563,42 @@ bool CUSBCECAdapterCommunication::SetControlledMode(bool controlled)
   return IsOpen() ? m_commands->SetControlledMode(controlled) : false;
 }
 
+uint16_t CUSBCECAdapterCommunication::GetPhysicalAddress(void)
+{
+  uint16_t iPA(0);
+
+  // try to get the PA from ADL
+#if defined(HAS_ADL_EDID_PARSER)
+  {
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address via ADL", __FUNCTION__);
+    CADLEdidParser adl;
+    iPA = adl.GetPhysicalAddress();
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - ADL returned physical address %04x", __FUNCTION__, iPA);
+  }
+#endif
+
+  // try to get the PA from the nvidia driver
+#if defined(HAS_NVIDIA_EDID_PARSER)
+  if (iPA == 0)
+  {
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address via nvidia driver", __FUNCTION__);
+    CNVEdidParser nv;
+    iPA = nv.GetPhysicalAddress();
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - nvidia driver returned physical address %04x", __FUNCTION__, iPA);
+  }
+#endif
+
+  // try to get the PA from the OS
+  if (iPA == 0)
+  {
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address from the OS", __FUNCTION__);
+    iPA = CEDIDParser::GetPhysicalAddress();
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - OS returned physical address %04x", __FUNCTION__, iPA);
+  }
+
+  return iPA;
+}
+
 void *CAdapterPingThread::Process(void)
 {
   while (!IsStopped())