cec: fixed - transmissions can come in while waiting for a response to a command
[deb_libcec.git] / src / lib / CECProcessor.cpp
index b305a4a06f2d51db77231840c40de72ba8c48d3b..e957a371c7a7c00fa2901a8b067c504938a7c80b 100644 (file)
@@ -187,7 +187,7 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint
 
   /* open a new connection */
   unsigned iConnectTry(0);
-  while (timeout.TimeLeft() > 0 && (bReturn = m_communication->Open(this, (timeout.TimeLeft() / CEC_CONNECT_TRIES), false, bStartListening)) == 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();
@@ -253,7 +253,7 @@ 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);
 
-  if (m_configuration.bActivateSource == 1)
+  if (bReturn && m_configuration.bActivateSource == 1)
     m_busDevices[m_configuration.logicalAddresses.primary]->ActivateSource();
 
   SetInitialised(bReturn);
@@ -456,23 +456,27 @@ void CCECProcessor::ReplaceHandlers(void)
 
 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;
@@ -510,7 +514,8 @@ bool CCECProcessor::SetActiveSource(uint16_t iStreamPath)
 {
   bool bReturn(false);
 
-  CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamPath);
+  // suppress polls when searching for a device
+  CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamPath, false, true);
   if (device)
   {
     device->SetActiveSource();
@@ -574,6 +579,12 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort,
 {
   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;
@@ -769,7 +780,7 @@ uint8_t CCECProcessor::MuteAudio(bool bSendRelease /* = true */)
   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];
@@ -777,7 +788,7 @@ CCECBusDevice *CCECProcessor::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddre
   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;
@@ -1495,7 +1506,8 @@ bool CCECProcessor::PingAdapter(void)
 
 void CCECProcessor::HandlePoll(cec_logical_address initiator, cec_logical_address destination)
 {
-  m_busDevices[destination]->HandlePoll(initiator);
+  if (destination < CECDEVICE_BROADCAST)
+    m_busDevices[destination]->HandlePollFrom(initiator);
 }
 
 bool CCECProcessor::HandleReceiveFailed(cec_logical_address initiator)
@@ -1546,9 +1558,12 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration)
   {
     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);
@@ -1602,6 +1617,7 @@ 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;
   m_configuration.powerOffDevices      = configuration->powerOffDevices;
@@ -1612,6 +1628,13 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration)
   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);
@@ -1664,8 +1687,12 @@ bool CCECProcessor::GetCurrentConfiguration(libcec_configuration *configuration)
     configuration->logicalAddresses    = m_configuration.logicalAddresses;
 
   // client version 1.6.0
-  if (configuration->clientVersion >= CEC_CLIENT_VERSION_1_5_3)
-    configuration->logicalAddresses    = m_configuration.logicalAddresses;
+  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;
 }