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);
+ }
+ }
}
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;
/*!
* @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;
};
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();
}
// 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:
#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>
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.
PLATFORM::CMutex m_mutex;
VCHI_INSTANCE_T m_vchi_instance;
VCHI_CONNECTION_T * m_vchi_connection;
+ CRPiCECAdapterFindNewLogicalAddress* m_laLost;
};
};