cec: moved the autodetect address api call to libcec_configuration. only send power...
authorLars Op den Kamp <lars@opdenkamp.eu>
Thu, 16 Feb 2012 09:07:23 +0000 (10:07 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Thu, 16 Feb 2012 09:07:23 +0000 (10:07 +0100)
include/cec.h
include/cectypes.h
src/LibCecSharp/CecSharpTypes.h
src/LibCecSharp/LibCecSharp.cpp
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/adapter/AdapterCommunication.h
src/lib/adapter/USBCECAdapterCommunication.h
src/lib/devices/CECBusDevice.cpp

index 1d36eb98ded34a299c3b48df92df97e3d17bdb82..cbc83463e6d327d2c953310e9cf54c3c7d1f1cca 100644 (file)
@@ -146,6 +146,7 @@ namespace CEC
     virtual bool SetPhysicalAddress(uint16_t iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS) = 0;
 
     /*!
+     * @deprecated Use libcec_configuration instead.
      * @brief Enable physical address detection (if the connected adapter supports this).
      * @return True when physical address detection was enabled, false otherwise.
      */
index fe8678f6df1d112ffbc04850a92f40234615e4d6..ca02f09487cc156d3971d08610502f16e44763cf 100644 (file)
@@ -952,9 +952,10 @@ typedef struct libcec_configuration
   cec_client_version    clientVersion;        /*!< the version of the client that is connecting */
   char                  strDeviceName[13];    /*!< how to name the device on the CEC bus */
   cec_device_type_list  deviceTypes;          /*!< the CEC device types to emulate */
-  uint16_t              iPhysicalAddress;     /*!< the physical address of the CEC adapter */
-  cec_logical_address   baseDevice;           /*!< the logical address of the device to which the adapter is connected. only used when iPhysicalAddress = 0 */
-  uint8_t               iHDMIPort;            /*!< the HDMI port to which the adapter is connected. only used when iPhysicalAddress = 0 */
+  uint8_t               bAutodetectAddress;   /*!< try to autodetect the physical address when 1 */
+  uint16_t              iPhysicalAddress;     /*!< the physical address of the CEC adapter. only used when bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
+  cec_logical_address   baseDevice;           /*!< the logical address of the device to which the adapter is connected. only used when iPhysicalAddress = 0 and bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
+  uint8_t               iHDMIPort;            /*!< the HDMI port to which the adapter is connected. only used when iPhysicalAddress = 0 and bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
   cec_vendor_id         tvVendor;             /*!< override the vendor ID of the TV. leave this untouched to autodetect */
   cec_logical_addresses wakeDevices;          /*!< wake these CEC devices when initialising libCEC or when calling PowerOnDevices() without any parameter */
   cec_logical_addresses powerOffDevices;      /*!< power off these devices when calling StandbyDevices() without any parameter */
@@ -982,6 +983,7 @@ typedef struct libcec_configuration
     wakeDevices.Clear();
     powerOffDevices.Clear();
 
+    bAutodetectAddress   = 1;
     bGetSettingsFromROM  = 0;
     bUseTVMenuLanguage   = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE;
     bActivateSource      = CEC_DEFAULT_SETTING_ACTIVATE_SOURCE;
index f385cdaa15264402487328daf2f608bfaffc7c2d..135eecf98ec84f7eb78c416f816061d4e98303b8 100644 (file)
@@ -519,6 +519,7 @@ namespace CecSharp
                {
                        DeviceName          = "";
                        DeviceTypes         = gcnew CecDeviceTypeList();
+                       AutodetectAddress  = true;
                        PhysicalAddress     = CEC_DEFAULT_PHYSICAL_ADDRESS;
                        BaseDevice          = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE;
                        HDMIPort            = CEC_DEFAULT_HDMI_PORT;
@@ -548,6 +549,7 @@ namespace CecSharp
 
                property System::String ^     DeviceName;
                property CecDeviceTypeList ^  DeviceTypes;
+               property bool                 AutodetectAddress;
                property uint16_t             PhysicalAddress;
                property CecLogicalAddress    BaseDevice;
                property uint8_t              HDMIPort;
index c02c4ea8a66c65546f9d5fbf4609276939dc325b..4bf39f06354378f82ab4d0fc4f9b13d5b707f33b 100644 (file)
@@ -93,12 +93,13 @@ namespace CecSharp
                        for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
                                config.deviceTypes.types[iPtr] = (cec_device_type)netConfig->DeviceTypes->Types[iPtr];
 
+                       config.bAutodetectAddress   = netConfig->AutodetectAddress ? 1 : 0;
                        config.iPhysicalAddress     = netConfig->PhysicalAddress;
                        config.baseDevice           = (cec_logical_address)netConfig->BaseDevice;
                        config.iHDMIPort            = netConfig->HDMIPort;
                        config.clientVersion        = (cec_client_version)netConfig->ClientVersion;
-                       config.bGetSettingsFromROM  = netConfig->GetSettingsFromROM;
-                       config.bActivateSource      = netConfig->ActivateSource;
+                       config.bGetSettingsFromROM  = netConfig->GetSettingsFromROM ? 1 : 0;
+                       config.bActivateSource      = netConfig->ActivateSource ? 1 : 0;
                        config.tvVendor             = (cec_vendor_id)netConfig->TvVendor;
                        config.wakeDevices.Clear();
                        for (int iPtr = 0; iPtr < 16; iPtr++)
@@ -112,8 +113,8 @@ namespace CecSharp
                                if (netConfig->PowerOffDevices->IsSet((CecLogicalAddress)iPtr))
                                        config.powerOffDevices.Set((cec_logical_address)iPtr);
                        }
-                       config.bPowerOffScreensaver = netConfig->PowerOffScreensaver;
-                       config.bPowerOffOnStandby   = netConfig->PowerOffOnStandby;
+                       config.bPowerOffScreensaver = netConfig->PowerOffScreensaver ? 1 : 0;
+                       config.bPowerOffOnStandby   = netConfig->PowerOffOnStandby ? 1 : 0;
                        config.callbacks            = &g_cecCallbacks;
                }
 
@@ -146,12 +147,17 @@ namespace CecSharp
                }
 
                void Close(void)
+               {
+                       DisableCallbacks();
+                       m_libCec->Close();
+               }
+
+               virtual void DisableCallbacks(void) override
                {
                        // delete the callbacks, since these might already have been destroyed in .NET
                        CecCallbackMethods::DisableCallbacks();
-                       m_libCec->EnableCallbacks(NULL, NULL);
-                       m_libCec->StandbyDevices();
-                       m_libCec->Close();
+                       if (m_libCec)
+                               m_libCec->EnableCallbacks(NULL, NULL);
                }
 
                virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) override
@@ -430,6 +436,7 @@ namespace CecSharp
 
                        if (m_libCec->GetCurrentConfiguration(&config))
                        {
+                               configuration->AutodetectAddress = config.bAutodetectAddress == 1;
                                configuration->BaseDevice = (CecLogicalAddress)config.baseDevice;
                                configuration->DeviceName = gcnew String(config.strDeviceName);
                                configuration->HDMIPort = config.iHDMIPort;
index 918d4e97d93d84456a8971723896d8b34c98346a..98be0c49229593c515ba451718763d5c20b95c96 100644 (file)
@@ -228,8 +228,6 @@ 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);
 
-  PowerOnDevices();
-
   SetInitialised(bReturn);
   CLibCEC::ConfigurationChanged(m_configuration);
 
@@ -510,6 +508,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]);
 }
 
@@ -548,10 +547,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;
 
@@ -560,9 +563,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)
@@ -582,10 +583,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;
 }
@@ -660,6 +658,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())
     {
@@ -953,6 +956,21 @@ 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)
@@ -1416,9 +1434,6 @@ bool CCECProcessor::SetStreamPath(uint16_t iPhysicalAddress)
 bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration)
 {
        bool bReinit(false);
-  bool bPhysicalAddressChanged(false);
-       bool bHdmiPortChanged(false);
-       bool bDeviceTypeChanged(false);
   CCECBusDevice *primary = IsRunning() ? GetPrimaryDevice() : NULL;
        cec_device_type oldPrimaryType = primary ? primary->GetType() : CEC_DEVICE_TYPE_RECORDING_DEVICE;
   m_configuration.clientVersion  = configuration->clientVersion;
@@ -1426,22 +1441,54 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration)
   // client version 1.5.0
 
   // device types
-  bDeviceTypeChanged |= 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
-  bPhysicalAddressChanged |= 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
-  bHdmiPortChanged |= 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
-  bHdmiPortChanged |= 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;
+       bReinit = bPhysicalAddressChanged || bHdmiPortChanged || bDeviceTypeChanged || bPhysicalAutodetected;
 
   // device name
   snprintf(m_configuration.strDeviceName, 13, "%s", configuration->strDeviceName);
@@ -1483,7 +1530,7 @@ bool CCECProcessor::SetConfiguration(const libcec_configuration *configuration)
                        return ChangeDeviceType(oldPrimaryType, m_configuration.deviceTypes[0]);
                else if (bPhysicalAddressChanged)
                        return SetPhysicalAddress(m_configuration.iPhysicalAddress);
-               else
+    else
       return SetHDMIPort(m_configuration.baseDevice, m_configuration.iHDMIPort);
   }
 
@@ -1496,6 +1543,7 @@ bool CCECProcessor::GetCurrentConfiguration(libcec_configuration *configuration)
   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;
index 2fc12e0666989a0d7b4aec030d68c9533d548262..9a6f842331e407b975644a5e3a599bd8989bb3f2 100644 (file)
@@ -105,7 +105,7 @@ namespace CEC
       virtual uint8_t MuteAudio(bool bSendRelease = true);
       virtual bool TransmitKeypress(cec_logical_address iDestination, cec_user_control_code key, bool bWait = true);
       virtual bool TransmitKeyRelease(cec_logical_address iDestination, bool bWait = true);
-      virtual bool EnablePhysicalAddressDetection(void) { return false; };
+      virtual bool EnablePhysicalAddressDetection(void);
       void SetStandardLineTimeout(uint8_t iTimeout);
       void SetRetryLineTimeout(uint8_t iTimeout);
       virtual bool GetCurrentConfiguration(libcec_configuration *configuration);
index 98ecd2e2a975c378756959799386f8cb396dc0b6..9ee29518d3a7cdac3d345ef413bbb2d1a055f93c 100644 (file)
@@ -148,5 +148,10 @@ namespace CEC
      * @return The name of the port
      */
     virtual CStdString GetPortName(void) = 0;
+
+    /*!
+     * @return The physical address, if the adapter supports this. 0 otherwise.
+     */
+    virtual uint16_t GetPhysicalAddress(void) = 0;
   };
 };
index 3a9ba515d02be277bd7356855e513ae7c82bf7c6..fc9e16ce044d30da4357288e88ed3b0ac1fd306e 100644 (file)
@@ -68,6 +68,7 @@ namespace CEC
     virtual bool SetControlledMode(bool controlled);
     virtual bool PersistConfiguration(libcec_configuration * UNUSED(configuration)) { return false; } // TODO
     virtual CStdString GetPortName(void);
+    virtual uint16_t GetPhysicalAddress(void) { return 0; }
 
     void *Process(void);
   private:
index a5d884e5e397b7424d66e78d397cf9277af8effe..3f82da62667b627c2dfe8262ba8e2680015db625 100644 (file)
@@ -117,11 +117,20 @@ bool CCECBusDevice::PowerOn(void)
   GetVendorId(); // ensure that we got the vendor id, because the implementations vary per vendor
 
   MarkBusy();
-  CLibCEC::AddLog(CEC_LOG_NOTICE, "<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
-  if (m_handler->PowerOn(GetMyLogicalAddress(), m_iLogicalAddress))
+  cec_power_status currentStatus = GetPowerStatus(false);
+  if (currentStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
+    currentStatus != CEC_POWER_STATUS_ON)
   {
-    SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
-    bReturn = true;
+    CLibCEC::AddLog(CEC_LOG_NOTICE, "<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    if (m_handler->PowerOn(GetMyLogicalAddress(), m_iLogicalAddress))
+    {
+      SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
+      bReturn = true;
+    }
+  }
+  else
+  {
+    CLibCEC::AddLog(CEC_LOG_NOTICE, "'%s' (%X) is already '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(currentStatus));
   }
 
   MarkReady();