{
CreateBusDevices();
m_configuration.Clear();
- m_configuration.serverVersion = configuration->serverVersion;
+ m_configuration.serverVersion = CEC_SERVER_VERSION_1_6_0;
SetConfiguration(configuration);
if (m_configuration.tvVendor != CEC_VENDOR_UNKNOWN)
m_iLastTransmission(0)
{
m_configuration.Clear();
- m_configuration.serverVersion = CEC_SERVER_VERSION_1_5_2;
+ m_configuration.serverVersion = CEC_SERVER_VERSION_1_6_0;
// client version < 1.5.0
m_configuration.clientVersion = (uint32_t)CEC_CLIENT_VERSION_PRE_1_5;
Close();
for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+ {
delete m_busDevices[iPtr];
+ m_busDevices[iPtr] = NULL;
+ }
}
void CCECProcessor::Close(void)
}
}
-bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint32_t iTimeoutMs)
+bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint32_t iTimeoutMs, bool bStartListening /* = true */)
{
bool bReturn(false);
Close();
/* open a new connection */
unsigned iConnectTry(0);
- while (timeout.TimeLeft() > 0 && (bReturn = m_communication->Open(this, (timeout.TimeLeft() / CEC_CONNECT_TRIES))) == false)
+ while (timeout.TimeLeft() > 0 && (bReturn = m_communication->Open((timeout.TimeLeft() / CEC_CONNECT_TRIES), false, bStartListening)) == false)
{
CLibCEC::AddLog(CEC_LOG_ERROR, "could not open a connection (try %d)", ++iConnectTry);
m_communication->Close();
}
if (bReturn)
- CLibCEC::AddLog(CEC_LOG_NOTICE, "connected to the CEC adapter. firmware version = %d, client version = %s", m_communication->GetFirmwareVersion(), ToString((cec_client_version)m_configuration.clientVersion));
+ {
+ m_configuration.iFirmwareVersion = m_communication->GetFirmwareVersion();
+ CLibCEC::AddLog(CEC_LOG_NOTICE, "connected to the CEC adapter. firmware version = %d, client version = %s", m_configuration.iFirmwareVersion, ToString((cec_client_version)m_configuration.clientVersion));
+ }
if (m_configuration.bGetSettingsFromROM == 1)
m_communication->GetConfiguration(&m_configuration);
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);
- if (m_configuration.bActivateSource == 1)
+ if (bReturn && m_configuration.bActivateSource == 1)
m_busDevices[m_configuration.logicalAddresses.primary]->ActivateSource();
SetInitialised(bReturn);
bool CCECProcessor::OnCommandReceived(const cec_command &command)
{
- ParseCommand(command);
- return true;
+ return m_inBuffer.Push(command);
}
void *CCECProcessor::Process(void)
{
CLibCEC::AddLog(CEC_LOG_DEBUG, "processor thread started");
+ cec_command command;
+ command.Clear();
+
while (!IsStopped() && m_communication->IsOpen())
{
+ if (m_inBuffer.Pop(command, 500))
+ ParseCommand(command);
+
if (IsInitialised())
{
ReplaceHandlers();
m_controller->CheckKeypressTimeout();
}
- Sleep(5);
}
return NULL;
{
bool bReturn(false);
- CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamPath);
+ // suppress polls when searching for a device
+ CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamPath, false, true);
if (device)
{
device->SetActiveSource();
{
bool bReturn(false);
+ // limit the HDMI port range to 1-15
+ if (iPort < 1)
+ iPort = 1;
+ if (iPort > 15)
+ iPort = 15;
+
{
CLockObject lock(m_mutex);
m_configuration.baseDevice = iBaseDevice;
return status;
}
-CCECBusDevice *CCECProcessor::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress, bool bRefresh /* = false */) const
+CCECBusDevice *CCECProcessor::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress, bool bRefresh /* = false */, bool bSuppressPoll /* = false */) const
{
if (m_busDevices[m_configuration.logicalAddresses.primary]->GetPhysicalAddress(false) == iPhysicalAddress)
return m_busDevices[m_configuration.logicalAddresses.primary];
CCECBusDevice *device = NULL;
for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
{
- if (m_busDevices[iPtr]->GetPhysicalAddress(bRefresh) == iPhysicalAddress)
+ if (m_busDevices[iPtr]->GetPhysicalAddress(bRefresh, bSuppressPoll) == iPhysicalAddress)
{
device = m_busDevices[iPtr];
break;
iMaxTries = m_busDevices[data.initiator]->GetHandler()->GetTransmitRetries() + 1;
}
- return m_communication->Write(data, iMaxTries, m_iLineTimeout, m_iRetryLineTimeout)
+ return m_communication->Write(data, iMaxTries, m_iStandardLineTimeout, m_iRetryLineTimeout)
== ADAPTER_MESSAGE_STATE_SENT_ACKED;
}
void CCECProcessor::ParseCommand(const cec_command &command)
{
CStdString dataStr;
- dataStr.Format(">> %1x%1x:%02x", command.initiator, command.destination, command.opcode);
+ dataStr.Format(">> %1x%1x", command.initiator, command.destination);
+ if (command.opcode_set == 1)
+ dataStr.AppendFormat(":%02x", command.opcode);
for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
dataStr.AppendFormat(":%02x", (unsigned int)command.parameters[iPtr]);
CLibCEC::AddLog(CEC_LOG_TRAFFIC, dataStr.c_str());
return "1.5.1";
case CEC_CLIENT_VERSION_1_5_2:
return "1.5.2";
+ case CEC_CLIENT_VERSION_1_5_3:
+ return "1.5.3";
+ case CEC_CLIENT_VERSION_1_6_0:
+ return "1.6.0";
default:
return "Unknown";
}
return "1.5.1";
case CEC_SERVER_VERSION_1_5_2:
return "1.5.2";
+ case CEC_SERVER_VERSION_1_5_3:
+ return "1.5.3";
+ case CEC_SERVER_VERSION_1_6_0:
+ return "1.6.0";
default:
return "Unknown";
}
void CCECProcessor::HandlePoll(cec_logical_address initiator, cec_logical_address destination)
{
- m_busDevices[initiator]->HandlePoll(destination);
+ if (destination < CECDEVICE_BROADCAST)
+ m_busDevices[destination]->HandlePollFrom(initiator);
}
bool CCECProcessor::HandleReceiveFailed(cec_logical_address initiator)
{
if (configuration->iPhysicalAddress != 0)
bPhysicalAddressChanged = IsRunning() && m_configuration.iPhysicalAddress != configuration->iPhysicalAddress;
- if (IsRunning())
- CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using physical address '%4x'", __FUNCTION__, configuration->iPhysicalAddress);
- m_configuration.iPhysicalAddress = configuration->iPhysicalAddress;
+ if (bPhysicalAddressChanged)
+ {
+ if (IsRunning())
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - using physical address '%4x'", __FUNCTION__, configuration->iPhysicalAddress);
+ m_configuration.iPhysicalAddress = configuration->iPhysicalAddress;
+ }
}
bool bHdmiPortChanged(false);
// just copy these
m_configuration.clientVersion = configuration->clientVersion;
+ m_configuration.bUseTVMenuLanguage = configuration->bUseTVMenuLanguage;
m_configuration.bActivateSource = configuration->bActivateSource;
m_configuration.bGetSettingsFromROM = configuration->bGetSettingsFromROM;
m_configuration.powerOffDevices = configuration->powerOffDevices;
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;
+ }
+
// ensure that there is at least 1 device type set
if (m_configuration.deviceTypes.IsEmpty())
m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
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;
+ }
+
return true;
}
for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
m_busDevices[iPtr]->GetStatus(true);
}
+
+bool CCECProcessor::GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs /* = 10000 */)
+{
+ if (!OpenConnection(strPort, 38400, iTimeoutMs, false))
+ return false;
+
+ config->iFirmwareVersion = m_communication->GetFirmwareVersion();
+ config->iPhysicalAddress = m_communication->GetPhysicalAddress();
+
+ delete m_communication;
+ m_communication = NULL;
+ return true;
+}