X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;h=643defad7cf17746f0fe4b452fd740353e6f631c;hb=44195125b9e12fafbba24ea0ae52795b7171703f;hp=ef2bbd10c4a0a7724b64d30223ee72d846a7a877;hpb=32403cc3b1abb8b186ca4bbe14cb7431a492f768;p=deb_libcec.git diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index ef2bbd1..643defa 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -66,7 +66,7 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, const libcec_configuration *co m_busDevices[CECDEVICE_TV]->ReplaceHandler(false); } -CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress, cec_client_version clientVersion) : +CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress) : m_bInitialised(false), m_communication(NULL), m_controller(controller), @@ -78,7 +78,7 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, con m_configuration.Clear(); // client version < 1.5.0 - m_configuration.clientVersion = clientVersion; + m_configuration.clientVersion = CEC_CLIENT_VERSION_PRE_1_5; snprintf(m_configuration.strDeviceName, 13, "%s", strDeviceName); m_configuration.deviceTypes = types; m_configuration.iPhysicalAddress = iPhysicalAddress; @@ -136,6 +136,8 @@ CCECProcessor::~CCECProcessor(void) void CCECProcessor::Close(void) { + StopThread(false); + SetInitialised(false); StopThread(); CLockObject lock(m_mutex); @@ -228,23 +230,12 @@ bool CCECProcessor::Initialise(void) else if (m_configuration.iPhysicalAddress == 0 && (bReturn = SetHDMIPort(m_configuration.baseDevice, m_configuration.iHDMIPort, true)) == false) CLibCEC::AddLog(CEC_LOG_ERROR, "unable to set HDMI port %d on %s (%x)", m_configuration.iHDMIPort, ToString(m_configuration.baseDevice), (uint8_t)m_configuration.baseDevice); - WakeDevices(); - SetInitialised(bReturn); CLibCEC::ConfigurationChanged(m_configuration); return bReturn; } -void CCECProcessor::WakeDevices(void) -{ - for (uint8_t iPtr = 0; iPtr <= 0xF; iPtr++) - { - if (m_configuration.wakeDevices[iPtr]) - m_busDevices[iPtr]->PowerOn(); - } -} - bool CCECProcessor::Start(const char *strPort, uint16_t iBaudRate /* = 38400 */, uint32_t iTimeoutMs /* = 10000 */) { bool bReturn(false); @@ -449,11 +440,14 @@ void *CCECProcessor::Process(void) while (!IsStopped() && m_communication->IsOpen()) { - ReplaceHandlers(); - if (m_commandBuffer.Pop(command)) - ParseCommand(command); + if (IsInitialised()) + { + ReplaceHandlers(); + if (m_commandBuffer.Pop(command)) + ParseCommand(command); - m_controller->CheckKeypressTimeout(); + m_controller->CheckKeypressTimeout(); + } Sleep(5); } @@ -516,6 +510,7 @@ void CCECProcessor::SetRetryLineTimeout(uint8_t iTimeout) bool CCECProcessor::SetActiveView(void) { + CLibCEC::AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__); return SetActiveSource(m_configuration.deviceTypes.IsEmpty() ? CEC_DEVICE_TYPE_RESERVED : m_configuration.deviceTypes[0]); } @@ -554,10 +549,14 @@ bool CCECProcessor::SetDeckInfo(cec_deck_info info, bool bSendUpdate /* = true * bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, bool bForce /* = false */) { bool bReturn(false); - CLockObject lock(m_mutex); - m_configuration.baseDevice = iBaseDevice; - m_configuration.iHDMIPort = iPort; + { + CLockObject lock(m_mutex); + m_configuration.baseDevice = iBaseDevice; + m_configuration.iHDMIPort = iPort; + m_configuration.bAutodetectAddress = false; + } + if (!IsRunning() && !bForce) return true; @@ -566,9 +565,7 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, uint16_t iPhysicalAddress(0); if (iBaseDevice > CECDEVICE_TV) { - lock.Unlock(); iPhysicalAddress = m_busDevices[iBaseDevice]->GetPhysicalAddress(); - lock.Lock(); } if (iPhysicalAddress < 0xffff) @@ -588,10 +585,7 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, if (!bReturn) CLibCEC::AddLog(CEC_LOG_ERROR, "failed to set the physical address"); else - { - lock.Unlock(); SetPhysicalAddress(iPhysicalAddress); - } return bReturn; } @@ -666,6 +660,11 @@ bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress, bool bSendUpda { CLockObject lock(m_mutex); m_configuration.iPhysicalAddress = iPhysicalAddress; + if (m_configuration.bAutodetectAddress) + { + m_configuration.baseDevice = CECDEVICE_UNKNOWN; + m_configuration.iHDMIPort = 0; + } if (!m_logicalAddresses.IsEmpty()) { @@ -859,13 +858,22 @@ bool CCECProcessor::IsActiveSource(cec_logical_address iAddress) bool CCECProcessor::Transmit(const cec_command &data) { + if (m_logicalAddresses[(uint8_t)data.destination]) + { + CLibCEC::AddLog(CEC_LOG_WARNING, "not sending data to myself!"); + return false; + } + cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN); { CLockObject lock(m_mutex); LogOutput(data); m_iLastTransmission = GetTimeMs(); - if (!m_communication) + if (!m_communication || !m_communication->IsOpen()) + { + CLibCEC::AddLog(CEC_LOG_ERROR, "cannot transmit command: connection closed"); return false; + } uint8_t iMaxTries = m_busDevices[data.initiator]->GetHandler()->GetTransmitRetries() + 1; retVal = m_communication->Write(data, iMaxTries, m_iLineTimeout, m_iRetryLineTimeout); } @@ -953,6 +961,53 @@ bool CCECProcessor::TransmitKeyRelease(cec_logical_address iDestination, bool bW return m_busDevices[iDestination]->TransmitKeyRelease(bWait); } +bool CCECProcessor::EnablePhysicalAddressDetection(void) +{ + CLibCEC::AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__); + uint16_t iPhysicalAddress = m_communication->GetPhysicalAddress(); + if (iPhysicalAddress != 0) + { + m_configuration.bAutodetectAddress = 1; + m_configuration.iPhysicalAddress = iPhysicalAddress; + m_configuration.baseDevice = CECDEVICE_UNKNOWN; + m_configuration.iHDMIPort = 0; + return SetPhysicalAddress(iPhysicalAddress); + } + return false; +} + +bool CCECProcessor::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) +{ + if (address == CECDEVICE_BROADCAST && m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0) + { + bool bReturn(true); + for (uint8_t iPtr = 0; iPtr <= 0xF; iPtr++) + { + if (m_configuration.powerOffDevices[iPtr]) + bReturn &= m_busDevices[iPtr]->Standby(); + } + return bReturn; + } + + return m_busDevices[address]->Standby(); +} + +bool CCECProcessor::PowerOnDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) +{ + if (address == CECDEVICE_BROADCAST && m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0) + { + bool bReturn(true); + for (uint8_t iPtr = 0; iPtr <= 0xF; iPtr++) + { + if (m_configuration.powerOffDevices[iPtr]) + bReturn &= m_busDevices[iPtr]->PowerOn(); + } + return bReturn; + } + + return m_busDevices[address]->PowerOn(); +} + const char *CCECProcessor::ToString(const cec_device_type type) { switch (type) @@ -1383,34 +1438,69 @@ bool CCECProcessor::SetStreamPath(uint16_t iPhysicalAddress) bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) { - bool bNeedsReinit(false); + bool bReinit(false); CCECBusDevice *primary = IsRunning() ? GetPrimaryDevice() : NULL; - m_configuration.clientVersion = configuration->clientVersion; + cec_device_type oldPrimaryType = primary ? primary->GetType() : CEC_DEVICE_TYPE_RECORDING_DEVICE; + m_configuration.clientVersion = configuration->clientVersion; // client version 1.5.0 // device types - bNeedsReinit |= IsRunning () && m_configuration.deviceTypes != configuration->deviceTypes; + bool bDeviceTypeChanged = IsRunning () && m_configuration.deviceTypes != configuration->deviceTypes; m_configuration.deviceTypes = configuration->deviceTypes; + // autodetect address + uint16_t iPhysicalAddress = IsRunning() && configuration->bAutodetectAddress ? m_communication->GetPhysicalAddress() : 0; + bool bPhysicalAutodetected = IsRunning() && configuration->bAutodetectAddress && iPhysicalAddress != m_configuration.iPhysicalAddress && iPhysicalAddress != 0; + if (bPhysicalAutodetected) + { + m_configuration.iPhysicalAddress = iPhysicalAddress; + m_configuration.bAutodetectAddress = true; + } + else + { + m_configuration.bAutodetectAddress = false; + } + // physical address - bNeedsReinit |= IsRunning() && m_configuration.iPhysicalAddress != configuration->iPhysicalAddress; - m_configuration.iPhysicalAddress = configuration->iPhysicalAddress; + bool bPhysicalAddressChanged(false); + if (!bPhysicalAutodetected) + { + bPhysicalAddressChanged = IsRunning() && m_configuration.iPhysicalAddress != configuration->iPhysicalAddress; + m_configuration.iPhysicalAddress = configuration->iPhysicalAddress; + } // base device - bNeedsReinit |= IsRunning() && m_configuration.baseDevice != configuration->baseDevice; - m_configuration.baseDevice = configuration->baseDevice; + bool bHdmiPortChanged(false); + if (!bPhysicalAutodetected && !bPhysicalAddressChanged) + { + bHdmiPortChanged = IsRunning() && m_configuration.baseDevice != configuration->baseDevice; + m_configuration.baseDevice = configuration->baseDevice; + } + else + { + m_configuration.baseDevice = CECDEVICE_UNKNOWN; + } // hdmi port - bNeedsReinit |= IsRunning() && m_configuration.iHDMIPort != configuration->iHDMIPort; - m_configuration.iHDMIPort = configuration->iHDMIPort; + if (!bPhysicalAutodetected && !bPhysicalAddressChanged) + { + bHdmiPortChanged |= IsRunning() && m_configuration.iHDMIPort != configuration->iHDMIPort; + m_configuration.iHDMIPort = configuration->iHDMIPort; + } + else + { + m_configuration.iHDMIPort = 0; + } + + bReinit = bPhysicalAddressChanged || bHdmiPortChanged || bDeviceTypeChanged || bPhysicalAutodetected; // device name snprintf(m_configuration.strDeviceName, 13, "%s", configuration->strDeviceName); if (primary && !primary->GetOSDName().Equals(m_configuration.strDeviceName)) { primary->SetOSDName(m_configuration.strDeviceName); - if (!bNeedsReinit && IsRunning()) + if (!bReinit && IsRunning()) primary->TransmitOSDName(CECDEVICE_TV); } @@ -1425,14 +1515,13 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) if (m_configuration.wakeDevices != configuration->wakeDevices) { m_configuration.wakeDevices = configuration->wakeDevices; - if (!bNeedsReinit && IsRunning()) - WakeDevices(); + if (!bReinit && IsRunning()) + PowerOnDevices(); } // just copy these m_configuration.bGetSettingsFromROM = configuration->bGetSettingsFromROM; - m_configuration.bPowerOnStartup = configuration->bPowerOnStartup; - m_configuration.bPowerOffShutdown = configuration->bPowerOffShutdown; + m_configuration.powerOffDevices = configuration->powerOffDevices; m_configuration.bPowerOffScreensaver = configuration->bPowerOffScreensaver; m_configuration.bPowerOffOnStandby = configuration->bPowerOffOnStandby; @@ -1440,11 +1529,14 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) if (m_configuration.deviceTypes.IsEmpty()) m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE); - if (bNeedsReinit) + if (bReinit) { - SetInitialised(false); - m_logicalAddresses.Clear(); - return Initialise(); + if (bDeviceTypeChanged) + return ChangeDeviceType(oldPrimaryType, m_configuration.deviceTypes[0]); + else if (bPhysicalAddressChanged) + return SetPhysicalAddress(m_configuration.iPhysicalAddress); + else + return SetHDMIPort(m_configuration.baseDevice, m_configuration.iHDMIPort); } return true; @@ -1452,20 +1544,18 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) bool CCECProcessor::GetCurrentConfiguration(libcec_configuration *configuration) { - m_configuration.tvVendor = m_busDevices[CECDEVICE_TV]->GetVendorId(); - // client version 1.5.0 configuration->clientVersion = m_configuration.clientVersion; snprintf(configuration->strDeviceName, 13, "%s", m_configuration.strDeviceName); configuration->deviceTypes = m_configuration.deviceTypes; + configuration->bAutodetectAddress = m_configuration.bAutodetectAddress; configuration->iPhysicalAddress = m_configuration.iPhysicalAddress; configuration->baseDevice = m_configuration.baseDevice; configuration->iHDMIPort = m_configuration.iHDMIPort; configuration->tvVendor = m_configuration.tvVendor; configuration->wakeDevices = m_configuration.wakeDevices; configuration->bGetSettingsFromROM = m_configuration.bGetSettingsFromROM; - configuration->bPowerOnStartup = m_configuration.bPowerOnStartup; - configuration->bPowerOffShutdown = m_configuration.bPowerOffShutdown; + configuration->powerOffDevices = m_configuration.powerOffDevices; configuration->bPowerOffScreensaver = m_configuration.bPowerOffScreensaver; configuration->bPowerOffOnStandby = m_configuration.bPowerOffOnStandby;