cec: poll for a vendor id when an active device is detected on a logical addres,...
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 26 Oct 2011 23:32:31 +0000 (01:32 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 26 Oct 2011 23:32:31 +0000 (01:32 +0200)
src/lib/CECBusDevice.cpp
src/lib/CECBusDevice.h
src/lib/CECProcessor.cpp
src/lib/implementations/ANCommandHandler.h
src/lib/implementations/CECCommandHandler.h
src/lib/implementations/SLCommandHandler.h

index 9eb2ed6e4d2aeb68efb543327ebbd04836730376..b3d338f03bfde4efedd213797e7651f331231477 100644 (file)
@@ -35,6 +35,7 @@
 #include "implementations/ANCommandHandler.h"
 #include "implementations/CECCommandHandler.h"
 #include "implementations/SLCommandHandler.h"
+#include "platform/timeutils.h"
 
 using namespace CEC;
 
@@ -43,7 +44,8 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi
   m_iLogicalAddress(iLogicalAddress),
   m_processor(processor),
   m_iVendorId(0),
-  m_iVendorClass(0)
+  m_iVendorClass(CEC_VENDOR_UNKNOWN),
+  m_iLastActive(0)
 {
   m_handler = new CCECCommandHandler(this);
 }
@@ -70,35 +72,61 @@ void CCECBusDevice::AddLog(cec_log_level level, const CStdString &strMessage)
 
 void CCECBusDevice::SetVendorId(uint16_t iVendorId, uint8_t iVendorClass /* = 0 */)
 {
-  delete m_handler;
   m_iVendorId = iVendorId;
   m_iVendorClass = iVendorClass;
 
   switch (iVendorId)
   {
   case CEC_VENDOR_SAMSUNG:
-    m_handler = new CANCommandHandler(this);
+    if (m_handler->GetVendorId() != CEC_VENDOR_SAMSUNG)
+    {
+      delete m_handler;
+      m_handler = new CANCommandHandler(this);
+    }
     break;
   case CEC_VENDOR_LG:
-    m_handler = new CSLCommandHandler(this);
+    if (m_handler->GetVendorId() != CEC_VENDOR_LG)
+    {
+      delete m_handler;
+      m_handler = new CSLCommandHandler(this);
+    }
     break;
   default:
-    m_handler = new CCECCommandHandler(this);
+    if (m_handler->GetVendorId() != CEC_VENDOR_UNKNOWN)
+    {
+      delete m_handler;
+      m_handler = new CCECCommandHandler(this);
+    }
     break;
   }
 
   CStdString strLog;
-  strLog.Format("device %d: vendor = %s (%04x) class = %2x", m_iLogicalAddress, CECVendorIdToString(iVendorId), iVendorId, iVendorClass);
+  strLog.Format("device %d: vendor = %s (%04x) class = %2x", m_iLogicalAddress, GetVendorName(), GetVendorId(), GetVendorClass());
   m_processor->AddLog(CEC_LOG_DEBUG, strLog.c_str());
 }
 
 bool CCECBusDevice::HandleCommand(const cec_command &command)
 {
   CLockObject lock(&m_mutex);
+  m_iLastActive = GetTimeMs();
   m_handler->HandleCommand(command);
   return true;
 }
 
+void CCECBusDevice::PollVendorId(void)
+{
+  CLockObject lock(&m_mutex);
+  if (m_iLastActive > 0 && m_iVendorId == CEC_VENDOR_UNKNOWN &&
+      GetTimeMs() - m_iLastActive > 5000)
+  {
+    m_iLastActive = GetTimeMs();
+
+    cec_command command;
+    cec_command::format(command, GetMyLogicalAddress(), GetLogicalAddress(), CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
+    m_processor->Transmit(command, false);
+  }
+}
+
 const char *CCECBusDevice::CECVendorIdToString(const uint64_t iVendorId)
 {
   switch (iVendorId)
index fc42556e320e2fc1f85268e7a77844a48b1cc8e6..613c766b387b50644de8d32489553cf33f33466c 100644 (file)
@@ -53,12 +53,20 @@ namespace CEC
     virtual uint16_t GetMyPhysicalAddress(void) const;
 
     virtual void SetVendorId(uint16_t iVendorId, uint8_t iVendorClass = 0);
+    virtual const char *GetVendorName(void) const { return CECVendorIdToString(m_iVendorId); }
+    virtual uint64_t GetVendorId(void) const { return m_iVendorId; }
+    virtual uint8_t GetVendorClass(void) const { return m_iVendorClass; }
+
+    virtual uint64_t GetLastActive(void) const { return m_iLastActive; }
+
     virtual bool HandleCommand(const cec_command &command);
 
     virtual void AddLog(cec_log_level level, const CStdString &strMessage);
     virtual CCECProcessor *GetProcessor() const { return m_processor; }
     virtual CCECCommandHandler *GetHandler(void) const { return m_handler; };
 
+    virtual void PollVendorId(void);
+
     static const char *CECVendorIdToString(const uint64_t iVendorId);
 
   protected:
@@ -68,6 +76,7 @@ namespace CEC
     CCECCommandHandler *m_handler;
     uint64_t            m_iVendorId;
     uint8_t             m_iVendorClass;
+    uint64_t            m_iLastActive;
     CMutex              m_mutex;
   };
 };
index e9caaf0835ba0cec3a4e83e72fb410541f825f35..648ec205babcd70cf6faf3b9e34ff1fea00048c7 100644 (file)
@@ -114,6 +114,9 @@ void *CCECProcessor::Process(void)
 
     m_controller->CheckKeypressTimeout();
 
+    for (unsigned int iDevicePtr = 0; iDevicePtr < 16; iDevicePtr++)
+      m_busDevices[iDevicePtr]->PollVendorId();
+
     if (!IsStopped())
       Sleep(5);
   }
index d1729aa2fefd696c9d20f5fa391d8d2e3da775ed..0207a6321f67c435c9d627b66481b0ca320446ee 100644 (file)
@@ -43,6 +43,8 @@ namespace CEC
 
     virtual bool HandleCommand(const cec_command &command);
 
+    virtual cec_vendor_id GetVendorId(void) { return CEC_VENDOR_SAMSUNG; };
+
   protected:
     virtual bool HandleVendorRemoteButtonDown(const cec_command &command);
   };
index 7129b400793ed473769f9b36b4c6be24799d16c4..7bb0fc253c13389383f8f7d1a159742941040e79 100644 (file)
@@ -44,6 +44,7 @@ namespace CEC
     virtual ~CCECCommandHandler(void) {};
 
     virtual bool HandleCommand(const cec_command &command);
+    virtual cec_vendor_id GetVendorId(void) { return CEC_VENDOR_UNKNOWN; };
 
   protected:
     bool HandleDeviceVendorCommandWithId(const cec_command &command);
index e5edac52116f57376d897157ce88c147666c3289..76a99701c0db91386a3492bb6bb2283b34e72e5b 100644 (file)
@@ -40,5 +40,6 @@ namespace CEC
   public:
     CSLCommandHandler(CCECBusDevice *busDevice);
     virtual ~CSLCommandHandler(void) {};
+    virtual cec_vendor_id GetVendorId(void) { return CEC_VENDOR_LG; };
   };
 };