Merge branch 'master' of github.com:Pulse-Eight/libcec
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 7 Dec 2011 22:57:53 +0000 (23:57 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 7 Dec 2011 22:57:53 +0000 (23:57 +0100)
include/cec.h
include/cecc.h
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/LibCECC.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h
src/lib/implementations/SLCommandHandler.cpp
src/testclient/main.cpp

index 44bf0244abdb8e6f5dbe29f59be811a28431223f..98adaf9309b7bc9119122b9eaf2419230deeb95a 100644 (file)
@@ -251,6 +251,13 @@ namespace CEC
      */
     virtual cec_power_status GetDevicePowerStatus(cec_logical_address iAddress) = 0;
 
+    /*!
+     * @brief Get the physical address of the device with the given logical address.
+     * @param iLogicalAddress The device to get the vendor id for.
+     * @return The physical address or 0 if it wasn't found.
+     */
+    virtual uint16_t GetDevicePhysicalAddress(cec_logical_address iAddress) = 0;
+
     /*!
      * @brief Sends a POLL message to a device.
      * @param iAddress The device to send the message to.
@@ -322,6 +329,19 @@ namespace CEC
      */
     virtual cec_osd_name GetOSDName(cec_logical_address iAddress) = 0;
 
+    /*!
+     * @brief Get the logical address of the device that is currently the active source on the CEC bus.
+     * @return The active source or CECDEVICE_UNKNOWN when unknown.
+     */
+    virtual cec_logical_address GetActiveSource(void) = 0;
+
+    /*!
+     * @brief Check whether a device is currently the active source on the CEC bus.
+     * @param iAddress The address to check.
+     * @return True when it is the active source, false otherwise.
+     */
+    virtual bool IsActiveSource(cec_logical_address iAddress) = 0;
+
     virtual const char *ToString(const cec_menu_state state) = 0;
     virtual const char *ToString(const cec_version version) = 0;
     virtual const char *ToString(const cec_power_status status) = 0;
index d433b3ebc50cfcf65482de567a116cf9cd5efafd..f270df7737a53e80ed1e10c44a3f6588ab68cb2d 100644 (file)
@@ -173,6 +173,24 @@ extern DECLSPEC uint64_t cec_get_device_vendor_id(CEC::cec_logical_address iLogi
 extern DECLSPEC uint64_t cec_get_device_vendor_id(cec_logical_address iLogicalAddress);
 #endif
 
+#ifdef __cplusplus
+extern DECLSPEC uint16_t cec_get_device_physical_address(CEC::cec_logical_address iLogicalAddress);
+#else
+extern DECLSPEC uint16_t cec_get_device_physical_address(cec_logical_address iLogicalAddress);
+#endif
+
+#ifdef __cplusplus
+extern DECLSPEC CEC::cec_logical_address cec_get_active_source(void);
+#else
+extern DECLSPEC cec_logical_address cec_get_active_source(void);
+#endif
+
+#ifdef __cplusplus
+extern DECLSPEC int cec_is_active_source(CEC::cec_logical_address iAddress);
+#else
+extern DECLSPEC int cec_is_active_source(cec_logical_address iAddress);
+#endif
+
 #ifdef __cplusplus
 extern DECLSPEC CEC::cec_power_status cec_get_device_power_status(CEC::cec_logical_address iLogicalAddress);
 #else
index 7a1dcad90a422eaa725500b5c4528c414703223d..e1e03b868d1ee6925bf319fd26c6f2b29fb801a8 100644 (file)
@@ -152,8 +152,10 @@ bool CCECProcessor::Start(const char *strPort, uint16_t iBaudRate /* = 38400 */,
     }
 
     lock.Leave();
-    if (SetAckMask(m_logicalAddresses.AckMask()) &&
-        SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true))
+
+    m_busDevices[CECDEVICE_TV]->GetVendorId();
+
+    if (SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true))
     {
       m_controller->AddLog(CEC_LOG_DEBUG, "processor thread started");
       m_busScan = new CCECBusScan(this);
@@ -260,8 +262,7 @@ void *CCECProcessor::Process(void)
   }
   else
   {
-    m_busDevices[CECDEVICE_TV]->GetVendorId();
-    m_busDevices[m_logicalAddresses.primary]->TransmitVendorID(CECDEVICE_TV, false);
+    SetAckMask(m_logicalAddresses.AckMask());
 
     CLockObject lock(&m_mutex);
     m_bStarted = true;
@@ -395,44 +396,54 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort,
 {
   bool bReturn(false);
 
-  CStdString strLog;
-  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;
 
+  CStdString strLog;
+  strLog.Format("setting HDMI port to %d on device %s (%d)", iPort, ToString(iBaseDevice), (int)iBaseDevice);
+  AddLog(CEC_LOG_DEBUG, strLog);
+
   uint16_t iPhysicalAddress(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)
+  if (iBaseDevice > CECDEVICE_TV)
+    iPhysicalAddress = m_busDevices[iBaseDevice]->GetPhysicalAddress();
+
+  if (iPhysicalAddress == 0xffff)
   {
-    iPhysicalAddress += (uint16_t)(iPort * iPos);
-    strLog.Format("checking physical address %4x", iPhysicalAddress);
-    AddLog(CEC_LOG_DEBUG, strLog);
-    if (PhysicalAddressInUse(iPhysicalAddress))
-    {
-      strLog.Format("physical address %4x is in use", iPhysicalAddress);
-      AddLog(CEC_LOG_DEBUG, strLog);
-      iPos = (iPos == 1) ? 0 : iPos / 0x10;
-    }
-    else
+    SetPhysicalAddress((uint16_t)iPort * 0x1000);
+    bReturn = false;
+  }
+  else
+  {
+    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)
     {
-      strLog.Format("physical address %4x is free", iPhysicalAddress);
+      iPhysicalAddress += (uint16_t)(iPort * iPos);
+      strLog.Format("checking physical address %4x", iPhysicalAddress);
       AddLog(CEC_LOG_DEBUG, strLog);
-      SetPhysicalAddress(iPhysicalAddress);
-      bReturn = true;
+      if (PhysicalAddressInUse(iPhysicalAddress))
+      {
+        strLog.Format("physical address %4x is in use", iPhysicalAddress);
+        AddLog(CEC_LOG_DEBUG, strLog);
+        iPos = (iPos == 1) ? 0 : iPos / 0x10;
+      }
+      else
+      {
+        strLog.Format("physical address %4x is free", iPhysicalAddress);
+        AddLog(CEC_LOG_DEBUG, strLog);
+        SetPhysicalAddress(iPhysicalAddress);
+        bReturn = true;
+      }
     }
   }
 
@@ -521,6 +532,7 @@ bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress)
     for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
       if (m_logicalAddresses[iPtr])
       {
+        m_busDevices[iPtr]->SetInactiveDevice();
         m_busDevices[iPtr]->SetPhysicalAddress(iPhysicalAddress);
         m_busDevices[iPtr]->TransmitPhysicalAddress();
       }
@@ -669,6 +681,13 @@ uint64_t CCECProcessor::GetDeviceVendorId(cec_logical_address iAddress)
   return false;
 }
 
+uint16_t CCECProcessor::GetDevicePhysicalAddress(cec_logical_address iAddress)
+{
+  if (m_busDevices[iAddress])
+    return m_busDevices[iAddress]->GetPhysicalAddress(false);
+  return false;
+}
+
 cec_power_status CCECProcessor::GetDevicePowerStatus(cec_logical_address iAddress)
 {
   if (m_busDevices[iAddress])
@@ -676,6 +695,22 @@ cec_power_status CCECProcessor::GetDevicePowerStatus(cec_logical_address iAddres
   return CEC_POWER_STATUS_UNKNOWN;
 }
 
+cec_logical_address CCECProcessor::GetActiveSource(void)
+{
+  for (uint8_t iPtr = 0; iPtr <= 11; iPtr++)
+  {
+    if (m_busDevices[iPtr]->IsActiveSource())
+      return (cec_logical_address)iPtr;
+  }
+
+  return CECDEVICE_UNKNOWN;
+}
+
+bool CCECProcessor::IsActiveSource(cec_logical_address iAddress)
+{
+  return m_busDevices[iAddress]->IsActiveSource();
+}
+
 bool CCECProcessor::Transmit(const cec_command &data)
 {
   bool bReturn(false);
@@ -1300,7 +1335,7 @@ void *CCECBusScan::Process(void)
 
   while (!IsStopped())
   {
-    if (++iCounter < 30)
+    if (++iCounter < 10)
     {
       Sleep(1000);
       continue;
index 75196eacaba51f516e1490e87694d0120ec94210..d2aa22206b046f3309e51ef22156df42686d10f6 100644 (file)
@@ -68,12 +68,15 @@ namespace CEC
       virtual cec_logical_address   GetLogicalAddress(void) const { return m_logicalAddresses.primary; }
       virtual cec_logical_addresses GetLogicalAddresses(void) const { return m_logicalAddresses; }
       virtual cec_logical_addresses GetActiveDevices(void);
+      virtual uint16_t              GetDevicePhysicalAddress(cec_logical_address iAddress);
       virtual bool                  HasLogicalAddress(cec_logical_address address) const { return m_logicalAddresses.IsSet(address); }
       virtual bool                  IsActiveDevice(cec_logical_address address);
       virtual bool                  IsActiveDeviceType(cec_device_type type);
       virtual uint16_t              GetPhysicalAddress(void) const;
       virtual uint64_t              GetLastTransmission(void) const { return m_iLastTransmission; }
       virtual bool                  IsStarted(void) const { return m_bStarted; }
+      virtual cec_logical_address   GetActiveSource(void);
+      virtual bool                  IsActiveSource(cec_logical_address iAddress);
 
       virtual bool SetActiveView(void);
       virtual bool SetActiveSource(cec_device_type type = CEC_DEVICE_TYPE_RESERVED);
index ebaae2db4584f4f04693adced24a9fc3fdf2f8ee..4156954e0acce84bf49f1d969e9c7cc06f9b0faf 100644 (file)
@@ -222,6 +222,25 @@ uint64_t CLibCEC::GetDeviceVendorId(cec_logical_address iAddress)
   return 0;
 }
 
+uint16_t CLibCEC::GetDevicePhysicalAddress(cec_logical_address iAddress)
+{
+  if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
+    return m_cec->GetDevicePhysicalAddress(iAddress);
+  return 0;
+}
+
+cec_logical_address CLibCEC::GetActiveSource(void)
+{
+  return m_cec ? m_cec->GetActiveSource() : CECDEVICE_UNKNOWN;
+}
+
+bool CLibCEC::IsActiveSource(cec_logical_address iAddress)
+{
+  if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
+    return m_cec->IsActiveSource(iAddress);
+  return false;
+}
+
 cec_power_status CLibCEC::GetDevicePowerStatus(cec_logical_address iAddress)
 {
   if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
index a0a4ddc373cdd97fdeb2c50996acdf9a4e28d9ef..02ea9c29a0f751eee1484b0c8ef46780bfd87fa0 100644 (file)
@@ -82,6 +82,7 @@ namespace CEC
       virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress);
       virtual bool GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language);
       virtual uint64_t GetDeviceVendorId(cec_logical_address iAddress);
+      virtual uint16_t GetDevicePhysicalAddress(cec_logical_address iAddress);
       virtual cec_power_status GetDevicePowerStatus(cec_logical_address iAddress);
       virtual bool PollDevice(cec_logical_address iAddress);
       virtual cec_logical_addresses GetActiveDevices(void);
@@ -95,6 +96,8 @@ namespace CEC
       virtual bool SendKeyRelease(cec_logical_address iDestination, bool bWait = false);
       virtual cec_osd_name GetOSDName(cec_logical_address iAddress);
       virtual bool EnablePhysicalAddressDetection(void);
+      virtual cec_logical_address GetActiveSource(void);
+      virtual bool IsActiveSource(cec_logical_address iAddress);
 
       const char *ToString(const cec_menu_state state);
       const char *ToString(const cec_version version);
index dc63c2927794ae768d1fd0698af1686036f6d778..28658cd2697636b4b4899f467ed36f62638f8e80 100644 (file)
@@ -247,6 +247,27 @@ uint64_t cec_get_device_vendor_id(cec_logical_address iLogicalAddress)
   return 0;
 }
 
+uint16_t cec_get_device_physical_address(cec_logical_address iLogicalAddress)
+{
+  if (cec_parser)
+    return cec_parser->GetDevicePhysicalAddress(iLogicalAddress);
+  return 0;
+}
+
+cec_logical_address cec_get_active_source(void)
+{
+  if (cec_parser)
+    return cec_parser->GetActiveSource();
+  return CECDEVICE_UNKNOWN;
+}
+
+int cec_is_active_source(cec_logical_address iAddress)
+{
+  if (cec_parser)
+    return cec_parser->IsActiveSource(iAddress);
+  return false;
+}
+
 cec_power_status cec_get_device_power_status(cec_logical_address iLogicalAddress)
 {
   if (cec_parser)
index 1793cc4c5af3431a42b07836908f85eee7b8ec55..8b4278119746c13a710102d3906958a063696d11 100644 (file)
@@ -84,6 +84,9 @@ bool CCECBusDevice::HandleCommand(const cec_command &command)
   {
     CLockObject lock(&m_writeMutex);
     m_iLastActive = GetTimeMs();
+
+    if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
+      m_deviceStatus = CEC_DEVICE_STATUS_PRESENT;
   }
 
   /* handle the command */
index 80576b4b003b81a8c416653d0ff47e20d5fda89d..14f3302952b6cdefcd85a10e943ab2786af6cc21 100644 (file)
@@ -72,6 +72,8 @@ namespace CEC
     virtual const char *          GetVendorName(bool bUpdate = false);
     virtual bool                  MyLogicalAddressContains(cec_logical_address address) const;
     virtual cec_bus_device_status GetStatus(bool bForcePoll = false);
+    virtual bool                  IsActiveSource(void) const { return m_bActiveSource; }
+
 
     virtual void SetInactiveDevice(void);
     virtual void SetActiveDevice(void);
index 713eebbde364432419673e8ba6593c987d6ceaf0..c23099eb0d2c408ba0ef6f37f7fccdef7055dcae 100644 (file)
@@ -256,7 +256,10 @@ bool CSLCommandHandler::InitHandler(void)
 
   CCECBusDevice *primary = m_processor->m_busDevices[m_processor->GetLogicalAddresses().primary];
   if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
+  {
     primary->SetVendorId(CEC_VENDOR_LG, false);
+    primary->TransmitVendorID(CECDEVICE_TV, false);
+  }
 
   if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV)
   {
@@ -286,6 +289,7 @@ bool CSLCommandHandler::InitHandler(void)
                        device->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE))
         {
           ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
+          ((CCECPlaybackDevice *)device)->TransmitDeckStatus(CECDEVICE_TV);
         }
       }
     }
index 7837c12a6a970554a7b569a52e069a78065fd426..d1ca8c19616a3b43446f5a0494588affd9e1c0eb 100644 (file)
@@ -720,21 +720,27 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string &argu
     {
       if (addresses[iPtr])
       {
-        uint64_t iVendorId      = parser->GetDeviceVendorId((cec_logical_address)iPtr);
-        cec_version iCecVersion = parser->GetDeviceCecVersion((cec_logical_address)iPtr);
-        cec_power_status power  = parser->GetDevicePowerStatus((cec_logical_address)iPtr);
-        cec_osd_name osdName    = parser->GetOSDName((cec_logical_address)iPtr);
+        uint64_t iVendorId        = parser->GetDeviceVendorId((cec_logical_address)iPtr);
+        bool     bActive          = parser->IsActiveSource((cec_logical_address)iPtr);
+        uint16_t iPhysicalAddress = parser->GetDevicePhysicalAddress((cec_logical_address)iPtr);
+        cec_version iCecVersion   = parser->GetDeviceCecVersion((cec_logical_address)iPtr);
+        cec_power_status power    = parser->GetDevicePowerStatus((cec_logical_address)iPtr);
+        cec_osd_name osdName      = parser->GetOSDName((cec_logical_address)iPtr);
+        CStdString strAddr;
+        strAddr.Format("%04x", iPhysicalAddress);
         cec_menu_language lang;
         lang.device = CECDEVICE_UNKNOWN;
         parser->GetDeviceMenuLanguage((cec_logical_address)iPtr, &lang);
 
         cout << "device #" << (int)iPtr << ": " << parser->ToString((cec_logical_address)iPtr) << endl;
-        cout << "vendor:       " << parser->ToString((cec_vendor_id)iVendorId) << endl;
-        cout << "osd string:   " << osdName.name << endl;
-        cout << "CEC version:  " << parser->ToString(iCecVersion) << endl;
-        cout << "power status: " << parser->ToString(power) << endl;
+        cout << "address:       " << strAddr.c_str() << endl;
+        cout << "active source: " << (bActive ? "yes" : "no") << endl;
+        cout << "vendor:        " << parser->ToString((cec_vendor_id)iVendorId) << endl;
+        cout << "osd string:    " << osdName.name << endl;
+        cout << "CEC version:   " << parser->ToString(iCecVersion) << endl;
+        cout << "power status:  " << parser->ToString(power) << endl;
         if ((uint8_t)lang.device == iPtr)
-          cout << "language:     " << lang.language << endl;
+          cout << "language:      " << lang.language << endl;
         cout << endl;
       }
     }