rpi: don't wait for a response (and fail) when opening a connection. issue #109
[deb_libcec.git] / src / lib / adapter / RPi / RPiCECAdapterCommunication.cpp
index 9176647f9f02630e212fa5d7363f84a26798620d..66c72c6b22a1793580354fa10b62a4ee4e74547b 100644 (file)
@@ -58,42 +58,18 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2
     static_cast<CRPiCECAdapterCommunication *>(callback_data)->OnDataReceived(p0, p1, p2, p3, p4);
 }
 
-CRPiCECAdapterFindNewLogicalAddress::CRPiCECAdapterFindNewLogicalAddress(CRPiCECAdapterCommunication* communication, const cec_logical_address address) :
-    m_communication(communication),
-    m_address(address) { }
-
-void *CRPiCECAdapterFindNewLogicalAddress::Process(void)
-{
-  cec_logical_address newAddress(CECDEVICE_UNKNOWN);
-  for (unsigned int iLA = CECDEVICE_RECORDINGDEVICE1; newAddress == CECDEVICE_UNKNOWN && iLA < CECDEVICE_BROADCAST; iLA++)
-  {
-    if (CCECTypeUtils::GetType((cec_logical_address)iLA) == CCECTypeUtils::GetType(m_address) &&
-        m_communication->SupportsSourceLogicalAddress((cec_logical_address)iLA) &&
-        m_communication->RegisterLogicalAddress((cec_logical_address)iLA))
-      newAddress = (cec_logical_address)iLA;
-  }
-
-  m_communication->m_callback->HandleLogicalAddressLost(m_address, newAddress);
-  return NULL;
-}
-
 CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
     IAdapterCommunication(callback),
     m_logicalAddress(CECDEVICE_UNKNOWN),
     m_bLogicalAddressChanged(false),
-    m_laLost(NULL)
+    m_previousLogicalAddress(CECDEVICE_FREEUSE),
+    m_bLogicalAddressRegistered(false)
 {
   m_queue = new CRPiCECAdapterMessageQueue(this);
 }
 
 CRPiCECAdapterCommunication::~CRPiCECAdapterCommunication(void)
 {
-  if (m_laLost)
-  {
-    m_laLost->StopThread();
-    delete m_laLost;
-    m_laLost = NULL;
-  }
   delete(m_queue);
   Close();
 }
@@ -135,7 +111,9 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
 {
   VC_CEC_NOTIFY_T reason = (VC_CEC_NOTIFY_T)CEC_CB_REASON(header);
 
+#ifdef CEC_DEBUGGING
   LIB_CEC->AddLog(CEC_LOG_DEBUG, "received data: header:%08X p0:%08X p1:%08X p2:%08X p3:%08X reason:%x", header, p0, p1, p2, p3, reason);
+#endif
 
   switch (reason)
   {
@@ -200,6 +178,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
   case VC_CEC_LOGICAL_ADDR:
     {
       CLockObject lock(m_mutex);
+      m_previousLogicalAddress = m_logicalAddress;
       if (CEC_CB_RC(header) == VCHIQ_SUCCESS)
       {
         m_bLogicalAddressChanged = true;
@@ -208,7 +187,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
       }
       else
       {
-        m_logicalAddress = CECDEVICE_BROADCAST;
+        m_logicalAddress = CECDEVICE_FREEUSE;
         LIB_CEC->AddLog(CEC_LOG_DEBUG, "failed to change the logical address, reset to %s (%x)", LIB_CEC->ToString(m_logicalAddress), m_logicalAddress);
       }
       m_logicalAddressCondition.Signal();
@@ -217,14 +196,17 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
   case VC_CEC_LOGICAL_ADDR_LOST:
     {
       // the logical address was taken by another device
-      cec_logical_address previousAddress = m_logicalAddress;
+      cec_logical_address previousAddress = m_logicalAddress == CECDEVICE_BROADCAST ? m_previousLogicalAddress : m_logicalAddress;
       m_logicalAddress = CECDEVICE_UNKNOWN;
 
-      if (m_laLost && !m_laLost->IsRunning())
-        delete m_laLost;
-      m_laLost = new CRPiCECAdapterFindNewLogicalAddress(this, previousAddress);
-      if (m_laLost)
-        m_laLost->CreateThread();
+      // notify libCEC that we lost our LA when the connection was initialised
+      bool bNotify(false);
+      {
+        CLockObject lock(m_mutex);
+        bNotify = m_bInitialised && m_bLogicalAddressRegistered;
+      }
+      if (bNotify)
+        m_callback->HandleLogicalAddressLost(previousAddress);
     }
     break;
   case VC_CEC_TOPOLOGY:
@@ -293,13 +275,8 @@ bool CRPiCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN
     // register the callback
     vc_cec_register_callback(((CECSERVICE_CALLBACK_T)rpi_cec_callback), (void*)this);
 
-    // release previous LA
+    // release previous LA, but don't wait for a response
     vc_cec_release_logical_address();
-    if (!m_logicalAddressCondition.Wait(m_mutex, m_bLogicalAddressChanged, iTimeoutMs))
-    {
-      LIB_CEC->AddLog(CEC_LOG_ERROR, "failed to release the previous LA");
-      return false;
-    }
 
     // register LA "freeuse"
     if (RegisterLogicalAddress(CECDEVICE_FREEUSE))
@@ -403,7 +380,11 @@ bool CRPiCECAdapterCommunication::UnregisterLogicalAddress(void)
     return true;
 
   LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - releasing previous logical address", __FUNCTION__);
-  m_bLogicalAddressChanged = false;
+  {
+    CLockObject lock(m_mutex);
+    m_bLogicalAddressRegistered = false;
+    m_bLogicalAddressChanged    = false;
+  }
 
   vc_cec_release_logical_address();
 
@@ -435,7 +416,12 @@ bool CRPiCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_addre
     return false;
   }
 
-  return m_logicalAddressCondition.Wait(m_mutex, m_bLogicalAddressChanged);
+  if (m_logicalAddressCondition.Wait(m_mutex, m_bLogicalAddressChanged))
+  {
+    m_bLogicalAddressRegistered = true;
+    return true;
+  }
+  return false;
 }
 
 cec_logical_addresses CRPiCECAdapterCommunication::GetLogicalAddresses(void)