rpi: handle VC_CEC_LOGICAL_ADDR_LOST in the rpi communication class itself, don't...
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 5 Sep 2012 09:15:09 +0000 (11:15 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 5 Sep 2012 13:07:59 +0000 (15:07 +0200)
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/adapter/AdapterCommunication.h
src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp
src/lib/adapter/RPi/RPiCECAdapterCommunication.h

index b4445f42f921881edb6361d57f45a7498c62136f..1eb272aa7197ba51db4c851b3cad825a0b706f36 100644 (file)
@@ -887,10 +887,18 @@ void CCECProcessor::SwitchMonitoring(bool bSwitchTo)
     UnregisterClients();
 }
 
-void CCECProcessor::HandleLogicalAddressLost(cec_logical_address address)
+void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress, cec_logical_address newAddress)
 {
-  m_libcec->AddLog(CEC_LOG_NOTICE, "logical address %x was taken by another device, re-registering the client");
-  CCECClient* client = GetClient(address);
+  m_libcec->AddLog(CEC_LOG_NOTICE, "logical address %x was taken by another device, changed to %x", oldAddress, newAddress);
+  CCECClient* client = GetClient(oldAddress);
   if (client)
-    RegisterClient(client);
+  {
+    if (newAddress == CECDEVICE_UNKNOWN)
+      UnregisterClient(client);
+    else
+    {
+      client->m_configuration.logicalAddresses.Unset(oldAddress);
+      client->m_configuration.logicalAddresses.Set(newAddress);
+    }
+  }
 }
index 63cf298b89cbfa644882d6b64e25e419c81457d4..3494d72a0e345fcb9abac76144b5303271cfdbf7 100644 (file)
@@ -69,7 +69,7 @@ namespace CEC
       CCECClient *GetClient(const cec_logical_address address);
 
       bool                  OnCommandReceived(const cec_command &command);
-      void                  HandleLogicalAddressLost(cec_logical_address address);
+      void                  HandleLogicalAddressLost(cec_logical_address oldAddress, cec_logical_address newAddress);
 
       CCECBusDevice *       GetDevice(cec_logical_address address) const;
       CCECAudioSystem *     GetAudioSystem(void) const;
index b73dccde19387ea99ac1f20d0c0071af4383b0e5..22e00cbef5998f7a324639e3da320a14feb5f128 100644 (file)
@@ -77,9 +77,10 @@ namespace CEC
 
     /*!
      * @brief Callback method for IAdapterCommunication, called when a logical address that libCEC uses was taken by another device.
-     * @param address The logical address that was taken by another device.
+     * @param oldAddress The logical address that was taken by another device.
+     * @param newAddress The new logical address, or CECDEVICE_UNKNOWN if no new LA could be allocated.
      */
-    virtual void HandleLogicalAddressLost(cec_logical_address address) = 0;
+    virtual void HandleLogicalAddressLost(cec_logical_address oldAddress, cec_logical_address newAddress) = 0;
 
     virtual CLibCEC *GetLib(void) const = 0;
   };
index 9e7f604c4aa337b279613a88db321b2f9dfade06..a89ebf6e79bac7d7a84dc8b08c861504138fc133 100644 (file)
@@ -58,16 +58,42 @@ 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_bLogicalAddressChanged(false),
+    m_laLost(NULL)
 {
   m_queue = new CRPiCECAdapterMessageQueue(this);
 }
 
 CRPiCECAdapterCommunication::~CRPiCECAdapterCommunication(void)
 {
+  if (m_laLost)
+  {
+    m_laLost->StopThread();
+    delete m_laLost;
+    m_laLost = NULL;
+  }
   delete(m_queue);
   Close();
 }
@@ -185,7 +211,12 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
       // the logical address was taken by another device
       cec_logical_address previousAddress = m_logicalAddress;
       m_logicalAddress = CECDEVICE_UNKNOWN;
-      m_callback->HandleLogicalAddressLost(previousAddress);
+
+      if (m_laLost && !m_laLost->IsRunning())
+        delete m_laLost;
+      m_laLost = new CRPiCECAdapterFindNewLogicalAddress(this, previousAddress);
+      if (m_laLost)
+        m_laLost->CreateThread();
     }
     break;
   case VC_CEC_TOPOLOGY:
index 01dbb5e51adbea0935fd5b538f458ada03aa5487..c874451227ccd0ab503f3a735341995b91027765 100644 (file)
@@ -34,7 +34,7 @@
 #if defined(HAVE_RPI_API)
 
 #include "lib/adapter/AdapterCommunication.h"
-#include "lib/platform/threads/mutex.h"
+#include "lib/platform/threads/threads.h"
 
 extern "C" {
 #include <interface/vmcs_host/vc_cecservice.h>
@@ -44,9 +44,22 @@ extern "C" {
 namespace CEC
 {
   class CRPiCECAdapterMessageQueue;
+  class CRPiCECAdapterCommunication;
+
+  class CRPiCECAdapterFindNewLogicalAddress : public PLATFORM::CThread
+  {
+  public:
+    CRPiCECAdapterFindNewLogicalAddress(CRPiCECAdapterCommunication* communication, const cec_logical_address address);
+    void *Process(void);
+  private:
+    CRPiCECAdapterCommunication* m_communication;
+    cec_logical_address          m_address;
+  };
 
   class CRPiCECAdapterCommunication : public IAdapterCommunication
   {
+    friend class CRPiCECAdapterFindNewLogicalAddress;
+
   public:
     /*!
      * @brief Create a new USB-CEC communication handler.
@@ -102,6 +115,7 @@ namespace CEC
     PLATFORM::CMutex            m_mutex;
     VCHI_INSTANCE_T             m_vchi_instance;
     VCHI_CONNECTION_T *         m_vchi_connection;
+    CRPiCECAdapterFindNewLogicalAddress* m_laLost;
   };
 };