X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;h=034c7e660c56de66d1702781d5f636b3716a71fe;hb=42d28d15d07f893b491051970ade1bd56bb596eb;hp=d9981b9368d37e8d53c86510bca6fb5a1337eaf4;hpb=4691dc3b885e390988f6104336afc682f3b157a2;p=deb_libcec.git diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index d9981b9..034c7e6 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -42,22 +42,23 @@ #include "implementations/CECCommandHandler.h" #include "LibCEC.h" #include "CECClient.h" +#include "CECTypeUtils.h" #include "platform/util/timeutils.h" +#include "platform/util/util.h" using namespace CEC; using namespace std; using namespace PLATFORM; #define CEC_PROCESSOR_SIGNAL_WAIT_TIME 1000 +#define ACTIVE_SOURCE_CHECK_TIMEOUT 10000 -#define ToString(x) m_libcec->ToString(x) +#define ToString(x) CCECTypeUtils::ToString(x) CCECProcessor::CCECProcessor(CLibCEC *libcec) : m_bInitialised(false), m_communication(NULL), m_libcec(libcec), - m_bMonitor(false), - m_iPreviousAckMask(0), m_iStandardLineTimeout(3), m_iRetryLineTimeout(3), m_iLastTransmission(0) @@ -68,7 +69,7 @@ CCECProcessor::CCECProcessor(CLibCEC *libcec) : CCECProcessor::~CCECProcessor(void) { Close(); - delete m_busDevices; + DELETE_AND_NULL(m_busDevices); } bool CCECProcessor::Start(const char *strPort, uint16_t iBaudRate /* = CEC_SERIAL_DEFAULT_BAUDRATE */, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */) @@ -88,9 +89,6 @@ bool CCECProcessor::Start(const char *strPort, uint16_t iBaudRate /* = CEC_SERIA } } - // mark as initialised - SetCECInitialised(true); - return true; } @@ -103,25 +101,15 @@ void CCECProcessor::Close(void) StopThread(); // close the connection - if (m_communication) - { - delete m_communication; - m_communication = NULL; - } + DELETE_AND_NULL(m_communication); } void CCECProcessor::ResetMembers(void) { // close the connection - if (m_communication) - { - delete m_communication; - m_communication = NULL; - } + DELETE_AND_NULL(m_communication); // reset the other members to the initial state - m_bMonitor = false; - m_iPreviousAckMask = 0; m_iStandardLineTimeout = 3; m_iRetryLineTimeout = 3; m_iLastTransmission = 0; @@ -160,6 +148,9 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint m_libcec->AddLog(CEC_LOG_NOTICE, "connection opened"); + // mark as initialised + SetCECInitialised(true); + return bReturn; } @@ -207,6 +198,19 @@ void CCECProcessor::ReplaceHandlers(void) it->second->ReplaceHandler(true); } +void CCECProcessor::CheckPendingActiveSource(void) +{ + if (!CECInitialised()) + return; + + // check each device + for (CECDEVICEMAP::iterator it = m_busDevices->Begin(); it != m_busDevices->End(); it++) + { + if (it->second->GetHandler()->ActiveSourcePending()) + it->second->ActivateSource(); + } +} + bool CCECProcessor::OnCommandReceived(const cec_command &command) { return m_inBuffer.Push(command); @@ -217,6 +221,7 @@ void *CCECProcessor::Process(void) m_libcec->AddLog(CEC_LOG_DEBUG, "processor thread started"); cec_command command; + CTimeout activeSourceCheck(ACTIVE_SOURCE_CHECK_TIMEOUT); // as long as we're not being stopped and the connection is open while (!IsStopped() && m_communication->IsOpen()) @@ -232,6 +237,13 @@ void *CCECProcessor::Process(void) // check if we need to replace handlers ReplaceHandlers(); + + // check whether we need to activate a source, if it failed before + if (activeSourceCheck.TimeLeft() == 0) + { + CheckPendingActiveSource(); + activeSourceCheck.Init(ACTIVE_SOURCE_CHECK_TIMEOUT); + } } } @@ -302,26 +314,6 @@ void CCECProcessor::LogOutput(const cec_command &data) m_libcec->AddLog(CEC_LOG_TRAFFIC, strTx.c_str()); } -bool CCECProcessor::SwitchMonitoring(bool bEnable) -{ - m_libcec->AddLog(CEC_LOG_NOTICE, "== %s monitoring mode ==", bEnable ? "enabling" : "disabling"); - - { - CLockObject lock(m_mutex); - // switch to monitoring mode, which will stop processing of incoming messages - m_bMonitor = bEnable; - // and store the current ackmask - m_iPreviousAckMask = m_communication->GetAckMask(); - } - - // set the mask to 0 when enabling monitor mode - if (bEnable) - return SetAckMask(0); - // and restore the previous mask otherwise - else - return SetAckMask(m_iPreviousAckMask); -} - bool CCECProcessor::PollDevice(cec_logical_address iAddress) { // try to find the primary device @@ -461,15 +453,11 @@ void CCECProcessor::ProcessCommand(const cec_command &command) dataStr.AppendFormat(":%02x", (unsigned int)command.parameters[iPtr]); m_libcec->AddLog(CEC_LOG_TRAFFIC, dataStr.c_str()); - // if we're not in monitor mode - if (!m_bMonitor) - { - // find the initiator - CCECBusDevice *device = m_busDevices->At(command.initiator); - // and "handle" the command - if (device) - device->HandleCommand(command); - } + // find the initiator + CCECBusDevice *device = m_busDevices->At(command.initiator); + + if (device) + device->HandleCommand(command); } bool CCECProcessor::IsPresentDevice(cec_logical_address address) @@ -542,7 +530,7 @@ bool CCECProcessor::StartBootloader(const char *strPort /* = NULL */) if (comm->IsOpen()) { bReturn = comm->StartBootloader(); - delete comm; + DELETE_AND_NULL(comm); } return bReturn; } @@ -643,15 +631,28 @@ CCECTuner *CCECProcessor::GetTuner(cec_logical_address address) const bool CCECProcessor::RegisterClient(CCECClient *client) { - if (!client || !IsRunning()) + if (!client) + return false; + + libcec_configuration &configuration = *client->GetConfiguration(); + + if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_3 && configuration.bMonitorOnly == 1) + return true; + + if (!CECInitialised()) + { + m_libcec->AddLog(CEC_LOG_ERROR, "failed to register a new CEC client: CEC processor is not initialised"); return false; + } + + // ensure that we know the vendor id of the TV + GetTV()->GetVendorId(CECDEVICE_UNREGISTERED); // unregister the client first if it's already been marked as registered if (client->IsRegistered()) UnregisterClient(client); // get the configuration from the client - libcec_configuration &configuration = *client->GetConfiguration(); m_libcec->AddLog(CEC_LOG_NOTICE, "registering new CEC client - v%s", ToString((cec_client_version)configuration.clientVersion)); // mark as uninitialised and unregistered @@ -722,13 +723,21 @@ bool CCECProcessor::RegisterClient(CCECClient *client) client->Alert(CEC_ALERT_SERVICE_DEVICE, param); } + // ensure that the command handler for the TV is initialised + if (bReturn) + { + CCECCommandHandler *handler = GetTV()->GetHandler(); + if (handler) + handler->InitHandler(); + } + return bReturn; } -void CCECProcessor::UnregisterClient(CCECClient *client) +bool CCECProcessor::UnregisterClient(CCECClient *client) { if (!client) - return; + return false; if (client->IsRegistered()) m_libcec->AddLog(CEC_LOG_NOTICE, "unregistering client: %s", client->GetConnectionInfo().c_str()); @@ -755,7 +764,7 @@ void CCECProcessor::UnregisterClient(CCECClient *client) } // set the new ackmask - SetAckMask(GetLogicalAddresses().AckMask()); + return SetAckMask(GetLogicalAddresses().AckMask()); } void CCECProcessor::UnregisterClients(void)