cec: specify the device on which the HDMI port will be selected in SetHDMIPort()
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 30 Nov 2011 18:12:32 +0000 (19:12 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 30 Nov 2011 18:12:32 +0000 (19:12 +0100)
include/cec.h
include/cecc.h
include/cectypes.h
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/LibCECC.cpp
src/testclient/main.cpp

index c1e48223805963fd4185bcdf7aa05df0183c35bf..6fef4827e75a0ec419b9403bf300a45032cec3e3 100644 (file)
@@ -265,10 +265,11 @@ namespace CEC
 
     /*!
      * @brief Changes the active HDMI port.
+     * @param iBaseDevice The device to which this libcec is connected.
      * @param iPort The new port number.
      * @return True when changed, false otherwise.
      */
-    virtual bool SetHDMIPort(uint8_t iPort) = 0;
+    virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort) = 0;
 
     /*!
      * @brief Sends a volume up keypress to an audiosystem if it's present.
index 6c28506cbffa49f08f12db8b42ab8cd7b416b12e..e2c09dab39e4a00e1cb7df4cb5dcc0e8c628a801 100644 (file)
@@ -185,7 +185,11 @@ extern DECLSPEC int cec_is_active_device_type(CEC::cec_device_type type);
 extern DECLSPEC int cec_is_active_device_type(cec_device_type type);
 #endif
 
-extern DECLSPEC int cec_set_hdmi_port(uint8_t iPort);
+#ifdef __cplusplus
+extern DECLSPEC int cec_set_hdmi_port(CEC::cec_logical_address iBaseDevice, uint8_t iPort);
+#else
+extern DECLSPEC int cec_set_hdmi_port(cec_logical_address iBaseDevice, uint8_t iPort);
+#endif
 
 extern DECLSPEC int cec_volume_up(int bWait);
 
index 59d32ae6ddfbcc48b2a6bb285f3c606be8ad90d2..0fed3b56723e76053de3c367a7e058513e96f9ca 100644 (file)
@@ -58,6 +58,7 @@ namespace CEC {
 //default physical address 1.0.0.0, HDMI port 1
 #define CEC_DEFAULT_PHYSICAL_ADDRESS 0x1000
 #define CEC_DEFAULT_HDMI_PORT        1
+#define CEC_DEFAULT_BASE_DEVICE      0
 #define MSGSTART                     0xFF
 #define MSGEND                       0xFE
 #define MSGESC                       0xFD
index 0a3e45d7bed7bf298c7fdbc46662ba01ab74411a..373c6f3322e995a226c914ed719873c9b4e52671 100644 (file)
@@ -50,6 +50,7 @@ using namespace std;
 CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) :
     m_bStarted(false),
     m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
+    m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
     m_strDeviceName(strDeviceName),
     m_communication(serComm),
     m_controller(controller),
@@ -66,6 +67,7 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm
 CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, const cec_device_type_list &types) :
     m_bStarted(false),
     m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
+    m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
     m_strDeviceName(strDeviceName),
     m_types(types),
     m_communication(serComm),
@@ -142,7 +144,7 @@ bool CCECProcessor::Start(void)
 
     lock.Leave();
     if (SetAckMask(m_logicalAddresses.AckMask()) &&
-        SetHDMIPort(m_iHDMIPort, true))
+        SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true))
     {
       m_busScan = new CCECBusScan(this);
       m_busScan->CreateThread(true);
@@ -349,30 +351,41 @@ bool CCECProcessor::SetDeckInfo(cec_deck_info info, bool bSendUpdate /* = true *
   return bReturn;
 }
 
-bool CCECProcessor::SetHDMIPort(uint8_t iPort, bool bForce /* = false */)
+bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, bool bForce /* = false */)
 {
   bool bReturn(false);
 
   CStdString strLog;
-  strLog.Format("setting HDMI port to %d", iPort);
+  strLog.Format("setting HDMI port to %d on device %s (%d)", iPort, ToString(iBaseDevice), (int)iBaseDevice);
   AddLog(CEC_LOG_DEBUG, strLog);
 
+  m_iBaseDevice = iBaseDevice;
   m_iHDMIPort = iPort;
   if (!m_bStarted && !bForce)
     return true;
 
   uint16_t iPhysicalAddress(0);
-  int iPos = 3;
-  while(!bReturn && iPos >= 0)
+  iPhysicalAddress = m_busDevices[iBaseDevice]->GetPhysicalAddress();
+  uint16_t iPos = 0;
+  if (iPhysicalAddress == 0)
+    iPos = 0x1000;
+  else if (iPhysicalAddress % 0x1000 == 0)
+    iPos = 0x100;
+  else if (iPhysicalAddress % 0x100 == 0)
+    iPos = 0x10;
+  else if (iPhysicalAddress % 0x10 == 0)
+    iPos = 0x1;
+
+  while(!bReturn && iPos > 0)
   {
-    iPhysicalAddress += ((uint16_t)iPort * (0x1 << iPos*4));
+    iPhysicalAddress += (uint16_t)(iPort * iPos);
     strLog.Format("checking physical address %4x", iPhysicalAddress);
     AddLog(CEC_LOG_DEBUG, strLog);
     if (CheckPhysicalAddress(iPhysicalAddress))
     {
       strLog.Format("physical address %4x is in use", iPhysicalAddress);
       AddLog(CEC_LOG_DEBUG, strLog);
-      iPos--;
+      iPos = (iPos == 1) ? 0 : iPos / 0x10;
     }
     else
     {
index d167b59217da3207e336a6dc7822c6003e6f9691..05dc4b28ae5c8c0382e5df8f223f5ca75491361c 100644 (file)
@@ -78,7 +78,7 @@ namespace CEC
       virtual bool SetActiveSource(cec_logical_address iAddress);
       virtual bool SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate = true);
       virtual bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true);
-      virtual bool SetHDMIPort(uint8_t iPort, bool bForce = false);
+      virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, bool bForce = false);
       virtual bool TransmitInactiveSource(void);
       virtual bool SetLogicalAddress(cec_logical_address iLogicalAddress);
       virtual bool SetMenuState(cec_menu_state state, bool bSendUpdate = true);
@@ -134,6 +134,7 @@ namespace CEC
 
       bool                   m_bStarted;
       uint8_t                m_iHDMIPort;
+      cec_logical_address    m_iBaseDevice;
       cec_command            m_currentframe;
       cec_logical_addresses  m_logicalAddresses;
       std::string            m_strDeviceName;
index 1ded155bbf233e2e59302ac89f1971182840f43f..118be7def567f54c2b3b4d2585b169e1d12c7483 100644 (file)
@@ -166,9 +166,9 @@ bool CLibCEC::SetPhysicalAddress(uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYS
   return m_cec ? m_cec->SetPhysicalAddress(iPhysicalAddress) : false;
 }
 
-bool CLibCEC::SetHDMIPort(uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
+bool CLibCEC::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
 {
-  return m_cec ? m_cec->SetHDMIPort(iPort) : false;
+  return m_cec ? m_cec->SetHDMIPort(iBaseDevice, iPort) : false;
 }
 
 bool CLibCEC::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */)
index 25b7fc12295528565cd750edb30ec653daf50e9f..c6bf62903ceec9614055c36b0fd807494e2733af 100644 (file)
@@ -87,7 +87,7 @@ namespace CEC
       virtual cec_logical_addresses GetActiveDevices(void);
       virtual bool IsActiveDevice(cec_logical_address iAddress);
       virtual bool IsActiveDeviceType(cec_device_type type);
-      virtual bool SetHDMIPort(uint8_t iPort = CEC_DEFAULT_HDMI_PORT);
+      virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort = CEC_DEFAULT_HDMI_PORT);
       virtual uint8_t VolumeUp(bool bWait = true);
       virtual uint8_t VolumeDown(bool bWait = true);
       virtual uint8_t MuteAudio(bool bWait = true);
index e71cd11a1ad5d008976627fb4db64d24b4ed6743..6c8d141c85ba5274ceca6450b52633b6a785a760 100644 (file)
@@ -265,10 +265,10 @@ int cec_is_active_device_type(cec_device_type type)
   return -1;
 }
 
-int cec_set_hdmi_port(uint8_t iPort)
+int cec_set_hdmi_port(cec_logical_address iBaseDevice, uint8_t iPort)
 {
   if (cec_parser)
-    return cec_parser->SetHDMIPort(iPort) ? 1 : 0;
+    return cec_parser->SetHDMIPort(iBaseDevice, iPort) ? 1 : 0;
   return -1;
 }
 
index cc3b2299dccd566cf0f186468cf09eebae94555d..1b13848021c7bc2bf694efa0f6af90dedf9f91f3 100644 (file)
@@ -227,7 +227,7 @@ void ShowHelpConsole(void)
   "[on] {address}            power on the device with the given logical address." << endl <<
   "[standby] {address}       put the device with the given address in standby mode." << endl <<
   "[la] {logical address}    change the logical address of the CEC adapter." << endl <<
-  "[p] {port number}         change the HDMI port number of the CEC adapter." << endl <<
+  "[p] {device} {port}       change the HDMI port number of the CEC adapter." << endl <<
   "[pa] {physical address}   change the physical address of the CEC adapter." << endl <<
   "[osd] {addr} {string}     set OSD message on the specified device." << endl <<
   "[ver] {addr}              get the CEC version of the specified device." << endl <<
@@ -445,7 +445,7 @@ int main (int argc, char *argv[])
 
   if (iHDMIPort > 0)
   {
-    parser->SetHDMIPort((uint8_t)iHDMIPort);
+    parser->SetHDMIPort((cec_logical_address)CEC_DEFAULT_BASE_DEVICE, (uint8_t)iHDMIPort);
     FlushLog(parser);
   }
 
@@ -560,10 +560,10 @@ int main (int argc, char *argv[])
         }
         else if (command == "p")
         {
-          string strvalue;
-          if (GetWord(input, strvalue))
+          string strPort, strDevice;
+          if (GetWord(input, strDevice) && GetWord(input, strPort))
           {
-            parser->SetHDMIPort((uint8_t)atoi(strvalue.c_str()));
+            parser->SetHDMIPort((cec_logical_address)atoi(strDevice.c_str()), (uint8_t)atoi(strPort.c_str()));
           }
         }
         else if (command == "pa")