+
+ bool bHdmiPortChanged(false);
+ if (!bPhysicalAutodetected && !IsValidPhysicalAddress(configuration->iPhysicalAddress))
+ {
+ // base device
+ bHdmiPortChanged = IsRunning() && m_configuration.baseDevice != configuration->baseDevice;
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using base device '%x'", __FUNCTION__, (int)configuration->baseDevice);
+ m_configuration.baseDevice = configuration->baseDevice;
+
+ // hdmi port
+ bHdmiPortChanged |= IsRunning() && m_configuration.iHDMIPort != configuration->iHDMIPort;
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using HDMI port '%d'", __FUNCTION__, configuration->iHDMIPort);
+ m_configuration.iHDMIPort = configuration->iHDMIPort;
+ }
+ else
+ {
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - resetting HDMI port and base device to defaults", __FUNCTION__);
+ m_configuration.baseDevice = CECDEVICE_UNKNOWN;
+ m_configuration.iHDMIPort = CEC_HDMI_PORTNUMBER_NONE;
+ }
+
+ bReinit = bPhysicalAddressChanged || bHdmiPortChanged || bDeviceTypeChanged;
+
+ // device name
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using OSD name '%s'", __FUNCTION__, configuration->strDeviceName);
+ snprintf(m_configuration.strDeviceName, 13, "%s", configuration->strDeviceName);
+ if (primary && !primary->GetOSDName().Equals(m_configuration.strDeviceName))
+ {
+ primary->SetOSDName(m_configuration.strDeviceName);
+ if (!bReinit && IsRunning())
+ primary->TransmitOSDName(CECDEVICE_TV);
+ }
+
+ // tv vendor id override
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - vendor id '%s'", __FUNCTION__, ToString((cec_vendor_id)configuration->tvVendor));
+ if (m_configuration.tvVendor != configuration->tvVendor)
+ {
+ m_configuration.tvVendor= configuration->tvVendor;
+ m_busDevices[CECDEVICE_TV]->SetVendorId((uint64_t)m_configuration.tvVendor);
+ }
+
+ // wake CEC devices
+ if (m_configuration.wakeDevices != configuration->wakeDevices)
+ {
+ m_configuration.wakeDevices = configuration->wakeDevices;
+ if (!bReinit && IsRunning())
+ PowerOnDevices();
+ }
+
+ // just copy these
+ m_configuration.bUseTVMenuLanguage = configuration->bUseTVMenuLanguage;
+ m_configuration.bActivateSource = configuration->bActivateSource;
+ m_configuration.bGetSettingsFromROM = configuration->bGetSettingsFromROM;
+ m_configuration.powerOffDevices = configuration->powerOffDevices;
+ m_configuration.bPowerOffScreensaver = configuration->bPowerOffScreensaver;
+ m_configuration.bPowerOffOnStandby = configuration->bPowerOffOnStandby;
+
+ // client version 1.5.1
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_5_1)
+ m_configuration.bSendInactiveSource = configuration->bSendInactiveSource;
+
+ // client version 1.6.0
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_6_0)
+ {
+ m_configuration.bPowerOffDevicesOnStandby = configuration->bPowerOffDevicesOnStandby;
+ m_configuration.bShutdownOnStandby = configuration->bShutdownOnStandby;
+ }
+
+ // client version 1.6.2
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_6_2)
+ {
+ memcpy(m_configuration.strDeviceLanguage, configuration->strDeviceLanguage, 3);
+ }
+
+ // ensure that there is at least 1 device type set
+ if (m_configuration.deviceTypes.IsEmpty())
+ m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+
+ bool bReturn(true);
+ if (bReinit || m_configuration.logicalAddresses.IsEmpty())
+ {
+ if (bDeviceTypeChanged)
+ bReturn = ChangeDeviceType(oldPrimaryType, m_configuration.deviceTypes[0]);
+ else if (IsValidPhysicalAddress(m_configuration.iPhysicalAddress))
+ bReturn = SetPhysicalAddress(m_configuration.iPhysicalAddress);
+ else if (m_configuration.baseDevice != CECDEVICE_UNKNOWN && m_configuration.iHDMIPort != CEC_HDMI_PORTNUMBER_NONE)
+ bReturn = SetHDMIPort(m_configuration.baseDevice, m_configuration.iHDMIPort);
+ }
+ else if (m_configuration.bActivateSource == 1 && IsRunning() && !IsActiveSource(m_configuration.logicalAddresses.primary))
+ {
+ // activate the source if we're not already the active source
+ SetActiveSource(m_configuration.deviceTypes.types[0]);
+ }
+
+ // persist the configuration
+ if (IsRunning())
+ m_communication->PersistConfiguration(&m_configuration);
+
+ return bReturn;
+}
+
+bool CCECProcessor::GetCurrentConfiguration(libcec_configuration *configuration)
+{
+ // client version 1.5.0
+ 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->clientVersion = m_configuration.clientVersion;
+ configuration->serverVersion = m_configuration.serverVersion;
+ configuration->tvVendor = m_configuration.tvVendor;
+
+ configuration->bGetSettingsFromROM = m_configuration.bGetSettingsFromROM;
+ configuration->bUseTVMenuLanguage = m_configuration.bUseTVMenuLanguage;
+ configuration->bActivateSource = m_configuration.bActivateSource;
+ configuration->wakeDevices = m_configuration.wakeDevices;
+ configuration->powerOffDevices = m_configuration.powerOffDevices;
+ configuration->bPowerOffScreensaver = m_configuration.bPowerOffScreensaver;
+ configuration->bPowerOffOnStandby = m_configuration.bPowerOffOnStandby;
+
+ // client version 1.5.1
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_5_1)
+ configuration->bSendInactiveSource = m_configuration.bSendInactiveSource;
+
+ // client version 1.5.3
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_5_3)
+ configuration->logicalAddresses = m_configuration.logicalAddresses;
+
+ // client version 1.6.0
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_6_0)
+ {
+ configuration->iFirmwareVersion = m_configuration.iFirmwareVersion;
+ configuration->bPowerOffDevicesOnStandby = m_configuration.bPowerOffDevicesOnStandby;
+ configuration->bShutdownOnStandby = m_configuration.bShutdownOnStandby;
+ }
+
+ // client version 1.6.2
+ if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_6_2)
+ {
+ memcpy(configuration->strDeviceLanguage, m_configuration.strDeviceLanguage, 3);
+ configuration->iFirmwareBuildDate = m_configuration.iFirmwareBuildDate;
+ }
+ return true;
+}
+
+bool CCECProcessor::CanPersistConfiguration(void)
+{
+ return m_communication ? m_communication->GetFirmwareVersion() >= 2 : false;
+}
+
+bool CCECProcessor::PersistConfiguration(libcec_configuration *configuration)
+{
+ return m_communication ? m_communication->PersistConfiguration(configuration) : false;
+}
+
+void CCECProcessor::RescanActiveDevices(void)
+{
+ for (uint8_t iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++)
+ m_busDevices[iPtr]->GetStatus(true);
+}
+
+bool CCECProcessor::GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
+{
+ if (!OpenConnection(strPort, CEC_SERIAL_DEFAULT_BAUDRATE, iTimeoutMs, false))
+ return false;
+
+ config->iFirmwareVersion = m_communication->GetFirmwareVersion();
+ config->iPhysicalAddress = m_communication->GetPhysicalAddress();
+ config->iFirmwareBuildDate = m_communication->GetFirmwareBuildDate();
+
+ return true;
+}
+
+bool CCECProcessor::TransmitPendingActiveSourceCommands(void)
+{
+ bool bReturn(true);
+ for (uint8_t iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++)
+ bReturn &= m_busDevices[iPtr]->TransmitPendingActiveSourceCommands();
+ return bReturn;
+}
+
+bool CCECProcessor::IsValidPhysicalAddress(uint16_t iPhysicalAddress)
+{
+ return iPhysicalAddress >= CEC_MIN_PHYSICAL_ADDRESS &&
+ iPhysicalAddress <= CEC_MAX_PHYSICAL_ADDRESS;