From: Lars Op den Kamp Date: Wed, 5 Sep 2012 09:15:09 +0000 (+0200) Subject: rpi: handle VC_CEC_LOGICAL_ADDR_LOST in the rpi communication class itself, don't... X-Git-Tag: upstream/2.2.0~1^2~18^2^2~13 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=f60ee8b35a31f8795658407a6863425a2c5c84d7;p=deb_libcec.git rpi: handle VC_CEC_LOGICAL_ADDR_LOST in the rpi communication class itself, don't try to re-register the client, as it will lead to problem (such as a deadlock when the vid of the tv isn't known). closes #41. closes #34 --- diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index b4445f4..1eb272a 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -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); + } + } } diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 63cf298..3494d72 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -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; diff --git a/src/lib/adapter/AdapterCommunication.h b/src/lib/adapter/AdapterCommunication.h index b73dccd..22e00cb 100644 --- a/src/lib/adapter/AdapterCommunication.h +++ b/src/lib/adapter/AdapterCommunication.h @@ -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; }; diff --git a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp index 9e7f604..a89ebf6 100644 --- a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp +++ b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp @@ -58,16 +58,42 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2 static_cast(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: diff --git a/src/lib/adapter/RPi/RPiCECAdapterCommunication.h b/src/lib/adapter/RPi/RPiCECAdapterCommunication.h index 01dbb5e..c874451 100644 --- a/src/lib/adapter/RPi/RPiCECAdapterCommunication.h +++ b/src/lib/adapter/RPi/RPiCECAdapterCommunication.h @@ -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 @@ -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; }; };