cec: add a physical address override parameter to libCEC's init method. when set...
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 8 Feb 2012 23:21:43 +0000 (00:21 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 8 Feb 2012 23:21:43 +0000 (00:21 +0100)
include/cec.h
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h

index 8780857988852a7f25b1fe1aa6b9da608b597c4f..9f152068627dfd6cc737145d623a2944d01407da 100644 (file)
@@ -386,9 +386,10 @@ namespace CEC
  * @brief Load the CEC adapter library.
  * @param strDeviceName How to present this device to other devices.
  * @param deviceTypes The device types to use on the CEC bus.
+ * @param iPhysicalAddress The physical address to assume on the bus. If set to 0, libCEC will try to autodetect the address, with the data provided via SetHDMIPort()
  * @return An instance of ICECAdapter or NULL on error.
  */
-extern "C" DECLSPEC void * CECInit(const char *strDeviceName, CEC::cec_device_type_list devicesTypes);
+extern "C" DECLSPEC void * CECInit(const char *strDeviceName, CEC::cec_device_type_list devicesTypes, uint16_t iPhysicalAddress = 0);
 
 /*!
  * @brief Unload the CEC adapter library.
index 1ecbd86d5b6ca8c684f4311110b96b27e935ed25..204f23bea8bc741b9e785076819ff684a9ed211f 100644 (file)
@@ -47,8 +47,9 @@ using namespace CEC;
 using namespace std;
 using namespace PLATFORM;
 
-CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types) :
+CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress /* = 0 */) :
     m_bInitialised(false),
+    m_iPhysicalAddress(iPhysicalAddress),
     m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
     m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
     m_strDeviceName(strDeviceName),
@@ -187,7 +188,13 @@ bool CCECProcessor::Initialise(void)
   m_busDevices[CECDEVICE_TV]->RequestVendorId();
   ReplaceHandlers();
 
-  if ((bReturn = SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true)) == false)
+  if (m_iPhysicalAddress != 0)
+  {
+    m_busDevices[m_logicalAddresses.primary]->m_iPhysicalAddress = m_iPhysicalAddress;
+    if ((bReturn = m_busDevices[m_logicalAddresses.primary]->TransmitPhysicalAddress()) == false)
+      CLibCEC::AddLog(CEC_LOG_ERROR, "unable to set the physical address to %4x", m_iPhysicalAddress);
+  }
+  else if (m_iPhysicalAddress == 0 && (bReturn = SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true)) == false)
     CLibCEC::AddLog(CEC_LOG_ERROR, "unable to set HDMI port %d on %s (%x)", m_iHDMIPort, ToString(m_iBaseDevice), (uint8_t)m_iBaseDevice);
 
   SetInitialised(bReturn);
@@ -515,6 +522,11 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort,
 {
   bool bReturn(false);
   CLockObject lock(m_mutex);
+  if (m_iPhysicalAddress != 0)
+  {
+    CLibCEC::AddLog(CEC_LOG_WARNING, "ignoring SetHDMIPort() call because a physical address is set");
+    return bReturn;
+  }
 
   m_iBaseDevice = iBaseDevice;
   m_iHDMIPort = iPort;
@@ -625,6 +637,8 @@ bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress, bool bSendUpda
 
   {
     CLockObject lock(m_mutex);
+    m_iPhysicalAddress = iPhysicalAddress;
+
     if (!m_logicalAddresses.IsEmpty())
     {
       bool bWasActiveSource(false);
index 53d9f6b5bfcf3da9e3e700e37f506c97c32624b5..5b6bd803d23fe2450790a28fa5c3eec9de035d7c 100644 (file)
@@ -46,7 +46,7 @@ namespace CEC
   class CCECProcessor : public PLATFORM::CThread, public IAdapterCommunicationCallback
   {
     public:
-      CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types);
+      CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress = 0);
       virtual ~CCECProcessor(void);
 
       virtual bool Start(const char *strPort, uint16_t iBaudRate = 38400, uint32_t iTimeoutMs = 10000);
@@ -147,6 +147,7 @@ namespace CEC
       void ParseCommand(const cec_command &command);
 
       bool                                m_bInitialised;
+      uint16_t                            m_iPhysicalAddress;
       uint8_t                             m_iHDMIPort;
       cec_logical_address                 m_iBaseDevice;
       cec_logical_addresses               m_logicalAddresses;
index e0cb4ea7bd71b43a8628b151baf1a4b68f3c4eab..ca83d5fc570ec0e8bef0e39a74af20a4cbb32152 100644 (file)
@@ -42,14 +42,14 @@ using namespace std;
 using namespace CEC;
 using namespace PLATFORM;
 
-CLibCEC::CLibCEC(const char *strDeviceName, cec_device_type_list types) :
+CLibCEC::CLibCEC(const char *strDeviceName, cec_device_type_list types, uint16_t iPhysicalAddress /* = 0 */) :
     m_iStartTime(GetTimeMs()),
     m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
     m_buttontime(0),
     m_callbacks(NULL),
     m_cbParam(NULL)
 {
-  m_cec = new CCECProcessor(this, strDeviceName, types);
+  m_cec = new CCECProcessor(this, strDeviceName, types, iPhysicalAddress);
 }
 
 CLibCEC::~CLibCEC(void)
@@ -457,7 +457,7 @@ void CLibCEC::SetInstance(CLibCEC *instance)
   g_libCEC_instance = instance;
 }
 
-void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types)
+void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types, uint16_t iPhysicalAddress /* = 0 */)
 {
   CLibCEC *lib = new CLibCEC(strDeviceName, types);
   CLibCEC::SetInstance(lib);
index 78881d9e339348a9853f1d21fa4a979c1b3fcb42..c3d044e0230287d742c22fd6a523cdd285f811b4 100644 (file)
@@ -47,7 +47,7 @@ namespace CEC
      * ICECAdapter implementation
      */
     //@{
-      CLibCEC(const char *strDeviceName, cec_device_type_list types);
+      CLibCEC(const char *strDeviceName, cec_device_type_list types, uint16_t iPhysicalAddress = 0);
       virtual ~CLibCEC(void);
 
       virtual bool Open(const char *strPort, uint32_t iTimeout = 10000);