X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;h=ad41d3c5f552fc5b854f556d732c2d074c387205;hb=c4483d6f83059251d529c8be45510734877477be;hp=34ffed58db84902d286a2532b78223f3b58af9c8;hpb=74c9d740fc14b30cefee2b4ad4d089d1004c5965;p=deb_libcec.git diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 34ffed5..ad41d3c 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -63,13 +63,17 @@ CCECProcessor::CCECProcessor(CLibCEC *libcec) : m_iStandardLineTimeout(3), m_iRetryLineTimeout(3), m_iLastTransmission(0), - m_bMonitor(true) + m_bMonitor(true), + m_addrAllocator(NULL), + m_bStallCommunication(false) { m_busDevices = new CCECDeviceMap(this); } CCECProcessor::~CCECProcessor(void) { + m_bStallCommunication = false; + DELETE_AND_NULL(m_addrAllocator); Close(); DELETE_AND_NULL(m_busDevices); } @@ -100,6 +104,8 @@ void CCECProcessor::Close(void) SetCECInitialised(false); // stop the processor + StopThread(-1); + m_inBuffer.Broadcast(); StopThread(); // close the connection @@ -218,7 +224,7 @@ void *CCECProcessor::Process(void) if (m_inBuffer.Pop(command, CEC_PROCESSOR_SIGNAL_WAIT_TIME)) ProcessCommand(command); - if (CECInitialised()) + if (CECInitialised() && !IsStopped()) { // check clients for keypress timeouts m_libcec->CheckKeypressTimeout(); @@ -410,6 +416,9 @@ bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) } } + // wait until we finished allocating a new LA if it got lost + while (m_bStallCommunication) Sleep(5); + { CLockObject lock(m_mutex); m_iLastTransmission = GetTimeMs(); @@ -430,7 +439,9 @@ bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) iLineTimeout = m_iRetryLineTimeout; } - return adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED; + return bIsReply ? + adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED || adapterState == ADAPTER_MESSAGE_STATE_SENT || adapterState == ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT : + adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED; } void CCECProcessor::TransmitAbort(cec_logical_address source, cec_logical_address destination, cec_opcode opcode, cec_abort_reason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */) @@ -684,6 +695,9 @@ bool CCECProcessor::AllocateLogicalAddresses(CCECClient* client) // set the new ackmask SetLogicalAddresses(GetLogicalAddresses()); + // resume outgoing communication + m_bStallCommunication = false; + return true; } @@ -841,7 +855,7 @@ bool CCECProcessor::UnregisterClient(CCECClient *client) void CCECProcessor::UnregisterClients(void) { - m_libcec->AddLog(CEC_LOG_NOTICE, "unregistering all CEC clients"); + m_libcec->AddLog(CEC_LOG_DEBUG, "unregistering all CEC clients"); vector clients = m_libcec->GetClients(); for (vector::iterator client = clients.begin(); client != clients.end(); client++) @@ -914,18 +928,42 @@ void CCECProcessor::SwitchMonitoring(bool bSwitchTo) UnregisterClients(); } -void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress, cec_logical_address newAddress) +void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress) { - m_libcec->AddLog(CEC_LOG_NOTICE, "logical address %x was taken by another device, changed to %x", oldAddress, newAddress); + // stall outgoing messages until we know our new LA + m_bStallCommunication = true; + + m_libcec->AddLog(CEC_LOG_NOTICE, "logical address %x was taken by another device, allocating a new address", oldAddress); CCECClient* client = GetClient(oldAddress); + if (!client) + client = GetPrimaryClient(); if (client) { - if (newAddress == CECDEVICE_UNKNOWN) - UnregisterClient(client); - else - { - client->m_configuration.logicalAddresses.Unset(oldAddress); - client->m_configuration.logicalAddresses.Set(newAddress); - } + if (m_addrAllocator) + while (m_addrAllocator->IsRunning()) Sleep(5); + delete m_addrAllocator; + + m_addrAllocator = new CCECAllocateLogicalAddress(this, client); + m_addrAllocator->CreateThread(); } } + +uint16_t CCECProcessor::GetAdapterVendorId(void) const +{ + return m_communication ? m_communication->GetAdapterVendorId() : 0; +} + +uint16_t CCECProcessor::GetAdapterProductId(void) const +{ + return m_communication ? m_communication->GetAdapterProductId() : 0; +} + +CCECAllocateLogicalAddress::CCECAllocateLogicalAddress(CCECProcessor* processor, CCECClient* client) : + m_processor(processor), + m_client(client) { } + +void* CCECAllocateLogicalAddress::Process(void) +{ + m_processor->AllocateLogicalAddresses(m_client); + return NULL; +}