From 7c5c5bf4a9f3bf8725b5018d6fe7add742edea14 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 16 Apr 2012 13:53:40 +0200 Subject: [PATCH] cec: persist settings directly when they're changed, only persist settings that actually changed, only instruct the device to persist the settings in eeprom when something changed, and don't persist settings on exit. bugzid: 715 --- include/cectypes.h | 4 +- src/lib/CECProcessor.cpp | 57 ++-- src/lib/adapter/USBCECAdapterCommands.cpp | 256 +++++++++++++----- src/lib/adapter/USBCECAdapterCommands.h | 150 +++++----- .../adapter/USBCECAdapterCommunication.cpp | 5 - 5 files changed, 301 insertions(+), 171 deletions(-) diff --git a/include/cectypes.h b/include/cectypes.h index 62b7b60..28c8d92 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -836,7 +836,7 @@ typedef struct cec_device_type_list return bReturn; } - bool IsEmpty() + bool IsEmpty() const { bool bReturn(true); for (unsigned int iPtr = 0; bReturn && iPtr < 5; iPtr++) @@ -1067,7 +1067,7 @@ typedef struct libcec_configuration bShutdownOnStandby = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY; bSendInactiveSource = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE; logicalAddresses.Clear(); - iFirmwareVersion = 0; + iFirmwareVersion = CEC_FW_VERSION_UNKNOWN; bPowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY; callbackParam = NULL; diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index a8f40c5..204a3c4 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -153,8 +153,6 @@ void CCECProcessor::Close(void) if (bClose && m_communication) { - m_communication->PersistConfiguration(&m_configuration); - m_communication->Close(); delete m_communication; m_communication = NULL; } @@ -176,13 +174,6 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint m_bConnectionOpened = (m_communication != NULL); } - /* check for an already opened connection */ - if (m_communication->IsOpen()) - { - CLibCEC::AddLog(CEC_LOG_ERROR, "connection already opened"); - return bReturn; - } - CTimeout timeout(iTimeoutMs > 0 ? iTimeoutMs : CEC_DEFAULT_TRANSMIT_WAIT); /* open a new connection */ @@ -201,7 +192,18 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint } if (m_configuration.bGetSettingsFromROM == 1) - m_communication->GetConfiguration(&m_configuration); + { + libcec_configuration config; + config.Clear(); + m_communication->GetConfiguration(&config); + + CLockObject lock(m_mutex); + if (!config.deviceTypes.IsEmpty()) + m_configuration.deviceTypes = config.deviceTypes; + if (config.iPhysicalAddress > 0) + m_configuration.iPhysicalAddress = config.iPhysicalAddress; + snprintf(m_configuration.strDeviceName, 13, "%s", config.strDeviceName); + } return bReturn; } @@ -722,7 +724,16 @@ bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress, bool bSendUpda SetActiveView(); if (bReturn) - CLibCEC::ConfigurationChanged(m_configuration); + { + libcec_configuration config; + { + CLockObject lock(m_mutex); + config = m_configuration; + } + + PersistConfiguration(&config); + CLibCEC::ConfigurationChanged(config); + } return bReturn; } @@ -1527,12 +1538,15 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) CCECBusDevice *primary = IsRunning() ? GetPrimaryDevice() : NULL; cec_device_type oldPrimaryType = primary ? primary->GetType() : CEC_DEVICE_TYPE_RECORDING_DEVICE; m_configuration.clientVersion = configuration->clientVersion; + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using client version '%s'", __FUNCTION__, ToString((cec_client_version)configuration->clientVersion)); // client version 1.5.0 // device types bool bDeviceTypeChanged = IsRunning () && m_configuration.deviceTypes != configuration->deviceTypes; m_configuration.deviceTypes = configuration->deviceTypes; + if (bDeviceTypeChanged) + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using primary device type '%s'", __FUNCTION__, ToString(configuration->deviceTypes[0])); bool bPhysicalAddressChanged(false); @@ -1545,6 +1559,8 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) { if (IsRunning()) CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - autodetected physical address '%4x'", __FUNCTION__, iPhysicalAddress); + else + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using physical address '%x'", __FUNCTION__, iPhysicalAddress); bPhysicalAddressChanged = (m_configuration.iPhysicalAddress != iPhysicalAddress); m_configuration.iPhysicalAddress = iPhysicalAddress; m_configuration.iHDMIPort = 0; @@ -1560,8 +1576,7 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) bPhysicalAddressChanged = IsRunning() && m_configuration.iPhysicalAddress != configuration->iPhysicalAddress; if (bPhysicalAddressChanged) { - if (IsRunning()) - CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using physical address '%4x'", __FUNCTION__, configuration->iPhysicalAddress); + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - physical address '%x'", __FUNCTION__, configuration->iPhysicalAddress); m_configuration.iPhysicalAddress = configuration->iPhysicalAddress; } } @@ -1571,20 +1586,17 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) { // base device bHdmiPortChanged = IsRunning() && m_configuration.baseDevice != configuration->baseDevice; - if (IsRunning()) - CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using base device '%x'", __FUNCTION__, (int)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; - if (IsRunning()) - CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using HDMI port '%d'", __FUNCTION__, configuration->iHDMIPort); + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using HDMI port '%d'", __FUNCTION__, configuration->iHDMIPort); m_configuration.iHDMIPort = configuration->iHDMIPort; } else { - if (IsRunning()) - CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - resetting HDMI port and base device to defaults", __FUNCTION__); + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - resetting HDMI port and base device to defaults", __FUNCTION__); m_configuration.baseDevice = CECDEVICE_UNKNOWN; m_configuration.iHDMIPort = 0; } @@ -1592,6 +1604,7 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) 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)) { @@ -1601,6 +1614,7 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) } // 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; @@ -1616,7 +1630,6 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) } // just copy these - m_configuration.clientVersion = configuration->clientVersion; m_configuration.bUseTVMenuLanguage = configuration->bUseTVMenuLanguage; m_configuration.bActivateSource = configuration->bActivateSource; m_configuration.bGetSettingsFromROM = configuration->bGetSettingsFromROM; @@ -1639,6 +1652,10 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration) if (m_configuration.deviceTypes.IsEmpty()) m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE); + // persist the configuration + if (IsRunning()) + m_communication->PersistConfiguration(&m_configuration); + if (bReinit) { if (bDeviceTypeChanged) diff --git a/src/lib/adapter/USBCECAdapterCommands.cpp b/src/lib/adapter/USBCECAdapterCommands.cpp index 38e1950..69a2632 100644 --- a/src/lib/adapter/USBCECAdapterCommands.cpp +++ b/src/lib/adapter/USBCECAdapterCommands.cpp @@ -37,6 +37,17 @@ using namespace CEC; using namespace PLATFORM; +CUSBCECAdapterCommands::CUSBCECAdapterCommands(CUSBCECAdapterCommunication *comm) : + m_comm(comm), + m_bSettingsRetrieved(false), + m_bSettingAutoEnabled(false), + m_settingCecVersion(CEC_VERSION_UNKNOWN), + m_iSettingLAMask(0), + m_bNeedsWrite(false) +{ + m_persistedConfiguration.Clear(); +} + cec_datapacket CUSBCECAdapterCommands::RequestSetting(cec_adapter_messagecode msgCode) { cec_datapacket retVal; @@ -56,15 +67,15 @@ cec_datapacket CUSBCECAdapterCommands::RequestSetting(cec_adapter_messagecode ms uint16_t CUSBCECAdapterCommands::RequestFirmwareVersion(void) { - m_iFirmwareVersion = CEC_FW_VERSION_UNKNOWN; + m_persistedConfiguration.iFirmwareVersion = CEC_FW_VERSION_UNKNOWN; unsigned int iFwVersionTry(0); - while (m_iFirmwareVersion == CEC_FW_VERSION_UNKNOWN && iFwVersionTry++ < 3) + while (m_persistedConfiguration.iFirmwareVersion == CEC_FW_VERSION_UNKNOWN && iFwVersionTry++ < 3) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting the firmware version"); cec_datapacket response = RequestSetting(MSGCODE_FIRMWARE_VERSION); if (response.size == 2) - m_iFirmwareVersion = (response[0] << 8 | response[1]); + m_persistedConfiguration.iFirmwareVersion = (response[0] << 8 | response[1]); else { CLibCEC::AddLog(CEC_LOG_WARNING, "the adapter did not respond with a correct firmware version (try %d)", iFwVersionTry); @@ -72,211 +83,321 @@ uint16_t CUSBCECAdapterCommands::RequestFirmwareVersion(void) } } - if (m_iFirmwareVersion == CEC_FW_VERSION_UNKNOWN) + if (m_persistedConfiguration.iFirmwareVersion == CEC_FW_VERSION_UNKNOWN) { CLibCEC::AddLog(CEC_LOG_DEBUG, "defaulting to firmware version 1"); - m_iFirmwareVersion = 1; + m_persistedConfiguration.iFirmwareVersion = 1; } - return m_iFirmwareVersion; + return m_persistedConfiguration.iFirmwareVersion; } -bool CUSBCECAdapterCommands::RequestSettingAutoEnabled(bool &enabled) +bool CUSBCECAdapterCommands::RequestSettingAutoEnabled(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting autonomous mode setting"); cec_datapacket response = RequestSetting(MSGCODE_GET_AUTO_ENABLED); if (response.size == 1) { - enabled = response[0] == 1; + m_bSettingAutoEnabled = response[0] == 1; return true; } return false; } -bool CUSBCECAdapterCommands::RequestSettingCECVersion(cec_version &version) +bool CUSBCECAdapterCommands::RequestSettingCECVersion(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting CEC version setting"); cec_datapacket response = RequestSetting(MSGCODE_GET_HDMI_VERSION); if (response.size == 1) { - version = (cec_version)response[0]; + m_settingCecVersion = (cec_version)response[0]; return true; } return false; } -bool CUSBCECAdapterCommands::RequestSettingDefaultLogicalAddress(cec_logical_address &address) +bool CUSBCECAdapterCommands::RequestSettingDefaultLogicalAddress(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting default logical address setting"); cec_datapacket response = RequestSetting(MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS); if (response.size == 1) { - address = (cec_logical_address)response[0]; + m_persistedConfiguration.logicalAddresses.primary = (cec_logical_address)response[0]; return true; } return false; } -bool CUSBCECAdapterCommands::RequestSettingDeviceType(cec_device_type &value) +bool CUSBCECAdapterCommands::RequestSettingDeviceType(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting device type setting"); + m_persistedConfiguration.deviceTypes.Clear(); cec_datapacket response = RequestSetting(MSGCODE_GET_DEVICE_TYPE); if (response.size == 1) { - value = (cec_device_type)response[0]; + m_persistedConfiguration.deviceTypes.Add((cec_device_type)response[0]); + CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted device type setting %s", CLibCEC::GetInstance()->ToString((cec_device_type)response[0])); return true; } + CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted device type setting"); return false; } -bool CUSBCECAdapterCommands::RequestSettingLogicalAddressMask(uint16_t &iMask) +bool CUSBCECAdapterCommands::RequestSettingLogicalAddressMask(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting logical address mask setting"); cec_datapacket response = RequestSetting(MSGCODE_GET_LOGICAL_ADDRESS_MASK); if (response.size == 2) { - iMask = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); + m_iSettingLAMask = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); return true; } return false; } -bool CUSBCECAdapterCommands::RequestSettingOSDName(CStdString &strOSDName) +bool CUSBCECAdapterCommands::RequestSettingOSDName(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting OSD name setting"); + memset(m_persistedConfiguration.strDeviceName, 0, 13); cec_datapacket response = RequestSetting(MSGCODE_GET_OSD_NAME); if (response.size == 0) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted device name setting"); return false; + } char buf[14]; for (uint8_t iPtr = 0; iPtr < response.size && iPtr < 13; iPtr++) buf[iPtr] = (char)response[iPtr]; buf[response.size] = 0; - strOSDName.Format("%s", buf); + snprintf(m_persistedConfiguration.strDeviceName, 13, "%s", buf); + CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted device name setting %s", buf); return true; } -bool CUSBCECAdapterCommands::RequestSettingPhysicalAddress(uint16_t &iPhysicalAddress) +bool CUSBCECAdapterCommands::RequestSettingPhysicalAddress(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting physical address setting"); cec_datapacket response = RequestSetting(MSGCODE_GET_PHYSICAL_ADDRESS); if (response.size == 2) { - iPhysicalAddress = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); + m_persistedConfiguration.iPhysicalAddress = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); + CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted physical address setting %4x", m_persistedConfiguration.iPhysicalAddress); return true; } + CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted physical address setting"); return false; } bool CUSBCECAdapterCommands::SetSettingAutoEnabled(bool enabled) { + bool bReturn(true); + + /* check whether this value was changed */ + if (m_bSettingAutoEnabled == enabled) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "autonomous mode setting unchanged (%s)", enabled ? "on" : "off"); + return bReturn; + } + + m_bNeedsWrite = true; CLibCEC::AddLog(CEC_LOG_DEBUG, "turning autonomous mode %s", enabled ? "on" : "off"); CCECAdapterMessage params; params.PushEscaped(enabled ? 1 : 0); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_AUTO_ENABLED, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + m_bSettingAutoEnabled = enabled; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingDeviceType(cec_device_type type) { - CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the device type to %1X", (uint8_t)type); + bool bReturn(true); + + /* check whether this value was changed */ + if (m_persistedConfiguration.deviceTypes.types[0] == type) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "device type setting unchanged (%X)", (uint8_t)type); + return bReturn; + } + + m_bNeedsWrite = true; + CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the device type to %X", (uint8_t)type); CCECAdapterMessage params; params.PushEscaped((uint8_t)type); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_DEVICE_TYPE, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingDefaultLogicalAddress(cec_logical_address address) { - CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the default logical address to %1X", address); + bool bReturn(true); + + /* check whether this value was changed */ + if (m_persistedConfiguration.logicalAddresses.primary == address) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "logical address setting unchanged (%X)", (uint8_t)address); + return bReturn; + } + + m_bNeedsWrite = true; + CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the default logical address to %X", (uint8_t)address); CCECAdapterMessage params; params.PushEscaped((uint8_t)address); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + m_persistedConfiguration.logicalAddresses.primary = address; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingLogicalAddressMask(uint16_t iMask) { + bool bReturn(true); + + /* check whether this value was changed */ + if (m_iSettingLAMask == iMask) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "logical address mask setting unchanged (%2X)", iMask); + return bReturn; + } + + m_bNeedsWrite = true; CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the logical address mask to %2X", iMask); CCECAdapterMessage params; params.PushEscaped(iMask >> 8); params.PushEscaped((uint8_t)iMask); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_LOGICAL_ADDRESS_MASK, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + m_iSettingLAMask = iMask; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingPhysicalAddress(uint16_t iPhysicalAddress) { + bool bReturn(true); + + /* check whether this value was changed */ + if (m_persistedConfiguration.iPhysicalAddress == iPhysicalAddress) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "logical address mask setting unchanged (%04X)", iPhysicalAddress); + return bReturn; + } + + m_bNeedsWrite = true; CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the physical address to %04X", iPhysicalAddress); CCECAdapterMessage params; params.PushEscaped(iPhysicalAddress >> 8); params.PushEscaped((uint8_t)iPhysicalAddress); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_PHYSICAL_ADDRESS, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + m_persistedConfiguration.iPhysicalAddress = iPhysicalAddress; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingCECVersion(cec_version version) { + bool bReturn(true); + + /* check whether this value was changed */ + if (m_settingCecVersion == version) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "CEC version setting unchanged (%s)", CLibCEC::GetInstance()->ToString(version)); + return bReturn; + } + + m_bNeedsWrite = true; CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the CEC version to %s", CLibCEC::GetInstance()->ToString(version)); CCECAdapterMessage params; params.PushEscaped((uint8_t)version); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_HDMI_VERSION, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + m_settingCecVersion = version; + return bReturn; } bool CUSBCECAdapterCommands::SetSettingOSDName(const char *strOSDName) { + bool bReturn(true); + + /* check whether this value was changed */ + if (!strcmp(m_persistedConfiguration.strDeviceName, strOSDName)) + { + CLibCEC::AddLog(CEC_LOG_DEBUG, "OSD name setting unchanged (%s)", strOSDName); + return bReturn; + } + CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the OSD name to %s", strOSDName); CCECAdapterMessage params; for (size_t iPtr = 0; iPtr < strlen(strOSDName); iPtr++) params.PushEscaped(strOSDName[iPtr]); CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_OSD_NAME, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; delete message; + + if (bReturn) + snprintf(m_persistedConfiguration.strDeviceName, 13, "%s", strOSDName); + return bReturn; } bool CUSBCECAdapterCommands::WriteEEPROM(void) { + if (!m_bNeedsWrite) + return true; + CLibCEC::AddLog(CEC_LOG_DEBUG, "writing settings in the EEPROM"); CCECAdapterMessage params; CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_WRITE_EEPROM, params); - bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; + m_bNeedsWrite = !(message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED); delete message; - return bReturn; + return m_bNeedsWrite; } bool CUSBCECAdapterCommands::PersistConfiguration(libcec_configuration *configuration) { - if (m_iFirmwareVersion < 2) + if (m_persistedConfiguration.iFirmwareVersion < 2) + return false; + + if (!RequestSettings()) return false; bool bReturn(true); @@ -287,52 +408,29 @@ bool CUSBCECAdapterCommands::PersistConfiguration(libcec_configuration *configur bReturn &= SetSettingPhysicalAddress(configuration->iPhysicalAddress); bReturn &= SetSettingCECVersion(CEC_VERSION_1_3A); bReturn &= SetSettingOSDName(configuration->strDeviceName); - if (bReturn) - bReturn = WriteEEPROM(); + bReturn &= WriteEEPROM(); return bReturn; } -bool CUSBCECAdapterCommands::GetConfiguration(libcec_configuration *configuration) +bool CUSBCECAdapterCommands::RequestSettings(void) { - configuration->iFirmwareVersion = m_iFirmwareVersion; - if (m_iFirmwareVersion < 2) - return false; - - bool bReturn(true); - cec_device_type type; - if (RequestSettingDeviceType(type)) - { - CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted device type setting %s", CLibCEC::GetInstance()->ToString(type)); - configuration->deviceTypes.Clear(); - configuration->deviceTypes.Add(type); - } - else + if (m_persistedConfiguration.iFirmwareVersion < 2) { - CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted device type setting"); - bReturn = false; + // settings can only be persisted with firmware v2+ + return false; } - if (RequestSettingPhysicalAddress(configuration->iPhysicalAddress)) - { - CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted physical address setting %4x", configuration->iPhysicalAddress); - } - else - { - CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted physical address setting"); - bReturn = false; - } + if (!m_bSettingsRetrieved) + return true; - CStdString strDeviceName; - if (RequestSettingOSDName(strDeviceName)) - { - snprintf(configuration->strDeviceName, 13, "%s", strDeviceName.c_str()); - CLibCEC::AddLog(CEC_LOG_DEBUG, "using persisted device name setting %s", configuration->strDeviceName); - } - else - { - CLibCEC::AddLog(CEC_LOG_DEBUG, "no persisted device name setting"); - bReturn = false; - } + bool bReturn(true); + bReturn &= RequestSettingAutoEnabled(); + bReturn &= RequestSettingCECVersion(); + bReturn &= RequestSettingDefaultLogicalAddress(); + bReturn &= RequestSettingDeviceType(); + bReturn &= RequestSettingLogicalAddressMask(); + bReturn &= RequestSettingOSDName(); + bReturn &= RequestSettingPhysicalAddress(); // don't read the following settings: // - auto enabled (always enabled) @@ -351,9 +449,27 @@ bool CUSBCECAdapterCommands::GetConfiguration(libcec_configuration *configuratio // - power off screensaver (1 bit) // - power off on standby (1 bit) // - send inactive source (1 bit) + + m_bSettingsRetrieved = true; + return bReturn; } +bool CUSBCECAdapterCommands::GetConfiguration(libcec_configuration *configuration) +{ + // get the settings from the eeprom if needed + if (!RequestSettings()) + return false; + + // copy the settings + configuration->iFirmwareVersion = m_persistedConfiguration.iFirmwareVersion; + configuration->deviceTypes = m_persistedConfiguration.deviceTypes; + configuration->iPhysicalAddress = m_persistedConfiguration.iPhysicalAddress; + snprintf(configuration->strDeviceName, 13, "%s", m_persistedConfiguration.strDeviceName); + + return true; +} + bool CUSBCECAdapterCommands::PingAdapter(void) { CLibCEC::AddLog(CEC_LOG_DEBUG, "sending ping"); diff --git a/src/lib/adapter/USBCECAdapterCommands.h b/src/lib/adapter/USBCECAdapterCommands.h index b5f12fb..b88651e 100644 --- a/src/lib/adapter/USBCECAdapterCommands.h +++ b/src/lib/adapter/USBCECAdapterCommands.h @@ -38,9 +38,7 @@ namespace CEC class CUSBCECAdapterCommands { public: - CUSBCECAdapterCommands(CUSBCECAdapterCommunication *comm) : - m_comm(comm), - m_iFirmwareVersion(CEC_FW_VERSION_UNKNOWN) {} + CUSBCECAdapterCommands(CUSBCECAdapterCommunication *comm); /*! * @brief Request the firmware version from the adapter. @@ -48,6 +46,67 @@ namespace CEC */ uint16_t RequestFirmwareVersion(void); + /*! + * @return The firmware version of the adapter, retrieved when the connection is opened. + */ + uint16_t GetFirmwareVersion(void) const { return m_persistedConfiguration.iFirmwareVersion; }; + + /*! + * @brief Persist the current configuration in the EEPROM. + * @attention Not all settings are persisted at this time. + * @param configuration The configuration to persist. + * @return True when persisted, false otherwise. + */ + bool PersistConfiguration(libcec_configuration *configuration); + + /*! + * @brief Get the persisted configuration from the EEPROM. + * @param configuration The persisted configuration. + * @return True when retrieved, false otherwise. + */ + bool GetConfiguration(libcec_configuration *configuration); + + /*! + * @brief Send a ping command to the adapter. + * @return True when acked by the adapter, false otherwise. + */ + bool PingAdapter(void); + + /*! + * @brief Change the ackmask of the adapter. + * @param iMask The new mask. + * @return True when the change was acked by the adapter, false otherwise. + */ + bool SetAckMask(uint16_t iMask); + + /*! + * @brief Put the adapter in bootloader mode. + * @attention The connection needs to be closed after this call, since the adapter will no longer be available. + * @return True when the command was sent, false otherwise. + */ + bool StartBootloader(void); + + /*! + * @brief Change the current CEC line timeout. + * @param iTimeout The new timeout. + * @return True when the change was acked by the adapter, false otherwise. + */ + bool SetLineTimeout(uint8_t iTimeout); + + /*! + * @brief Put the adapter in controlled or autonomous mode. + * @param controlled True to switch to controlled mode, false to switch to auto mode. + * @return True when acked by the controller, false otherwise. + */ + bool SetControlledMode(bool controlled); + + private: + /*! + * @brief Reads all settings from the eeprom. + * @return True when read, false otherwise. + */ + bool RequestSettings(void); + /*! * @brief Request a setting value from the adapter. * @param msgCode The setting to retrieve. @@ -64,10 +123,9 @@ namespace CEC /*! * @brief Request the value of the "auto enabled" setting from the adapter. - * @param enabled The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingAutoEnabled(bool &enabled); + bool RequestSettingAutoEnabled(void); /*! * @brief Change the value of the "device type" setting, used when the device is in autonomous mode. @@ -78,10 +136,9 @@ namespace CEC /*! * @brief Request the value of the "device type" setting from the adapter. - * @param type The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingDeviceType(cec_device_type &type); + bool RequestSettingDeviceType(void); /*! * @brief Change the value of the "default logical address" setting, used when the device is in autonomous mode. @@ -92,10 +149,9 @@ namespace CEC /*! * @brief Request the value of the "default logical address" setting from the adapter. - * @param address The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingDefaultLogicalAddress(cec_logical_address &address); + bool RequestSettingDefaultLogicalAddress(void); /*! * @brief Change the value of the "logical address mask" setting, used when the device is in autonomous mode. @@ -106,10 +162,9 @@ namespace CEC /*! * @brief Request the value of the "logical address mask" setting from the adapter. - * @param iMask The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingLogicalAddressMask(uint16_t &iMask); + bool RequestSettingLogicalAddressMask(void); /*! * @brief Change the value of the "physical address" setting, used when the device is in autonomous mode. @@ -120,10 +175,9 @@ namespace CEC /*! * @brief Request the value of the "physical address" setting from the adapter. - * @param iPhysicalAddress The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingPhysicalAddress(uint16_t &iPhysicalAddress); + bool RequestSettingPhysicalAddress(void); /*! * @brief Change the value of the "CEC version" setting, used when the device is in autonomous mode. @@ -134,10 +188,9 @@ namespace CEC /*! * @brief Request the value of the "CEC version" setting from the adapter. - * @param version The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingCECVersion(cec_version &version); + bool RequestSettingCECVersion(void); /*! * @brief Change the value of the "OSD name" setting, used when the device is in autonomous mode. @@ -148,10 +201,9 @@ namespace CEC /*! * @brief Request the value of the "OSD name" setting from the adapter. - * @param strOSDName The current value. * @return True when retrieved, false otherwise. */ - bool RequestSettingOSDName(CStdString &strOSDName); + bool RequestSettingOSDName(void); /*! * @brief Persist the current settings in the EEPROM @@ -159,62 +211,12 @@ namespace CEC */ bool WriteEEPROM(void); - /*! - * @return The firmware version of the adapter, retrieved when the connection is opened. - */ - uint16_t GetFirmwareVersion(void) const { return m_iFirmwareVersion; }; - - /*! - * @brief Persist the current configuration in the EEPROM. - * @attention Not all settings are persisted at this time. - * @param configuration The configuration to persist. - * @return True when persisted, false otherwise. - */ - bool PersistConfiguration(libcec_configuration *configuration); - - /*! - * @brief Get the persisted configuration from the EEPROM. - * @param configuration The persisted configuration. - * @return True when retrieved, false otherwise. - */ - bool GetConfiguration(libcec_configuration *configuration); - - /*! - * @brief Send a ping command to the adapter. - * @return True when acked by the adapter, false otherwise. - */ - bool PingAdapter(void); - - /*! - * @brief Change the ackmask of the adapter. - * @param iMask The new mask. - * @return True when the change was acked by the adapter, false otherwise. - */ - bool SetAckMask(uint16_t iMask); - - /*! - * @brief Put the adapter in bootloader mode. - * @attention The connection needs to be closed after this call, since the adapter will no longer be available. - * @return True when the command was sent, false otherwise. - */ - bool StartBootloader(void); - - /*! - * @brief Change the current CEC line timeout. - * @param iTimeout The new timeout. - * @return True when the change was acked by the adapter, false otherwise. - */ - bool SetLineTimeout(uint8_t iTimeout); - - /*! - * @brief Put the adapter in controlled or autonomous mode. - * @param controlled True to switch to controlled mode, false to switch to auto mode. - * @return True when acked by the controller, false otherwise. - */ - bool SetControlledMode(bool controlled); - - private: - CUSBCECAdapterCommunication *m_comm; /**< the communication handler */ - uint16_t m_iFirmwareVersion; /**< the firwmare version that was retrieved while opening the connection */ + CUSBCECAdapterCommunication *m_comm; /**< the communication handler */ + bool m_bSettingsRetrieved; /**< true when the settings were read from the eeprom, false otherwise */ + bool m_bSettingAutoEnabled; /**< the value of the auto-enabled setting */ + cec_version m_settingCecVersion; /**< the value of the cec version setting */ + uint16_t m_iSettingLAMask; /**< the value of the LA mask setting */ + bool m_bNeedsWrite; /**< true when we sent changed settings to the adapter that have not been persisted */ + libcec_configuration m_persistedConfiguration; /**< the configuration that is persisted in the eeprom */ }; } diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index d98c205..ef80ed0 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -146,11 +146,6 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */, bool b if (!bConnectionOpened || !bStartListening) StopThread(0); - if (!bConnectionOpened) - { - delete m_port; - m_port = NULL; - } return bConnectionOpened; } -- 2.34.1