cec: added some more audio related opcode handling. added TransmitVendorId(), but...
authorLars Op den Kamp <lars@opdenkamp.eu>
Fri, 11 Nov 2011 11:13:39 +0000 (12:13 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Fri, 11 Nov 2011 11:13:39 +0000 (12:13 +0100)
include/cectypes.h
src/lib/CECProcessor.cpp
src/lib/devices/CECAudioSystem.cpp
src/lib/devices/CECAudioSystem.h
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/CECCommandHandler.h

index 4e5413e46506aba88634be84d0f12a3faca322f4..258452d5688dab15f7459c36902c4c11ac350ad3 100644 (file)
@@ -103,7 +103,8 @@ typedef enum cec_version
   CEC_VERSION_1_2     = 0x01,
   CEC_VERSION_1_2A    = 0x02,
   CEC_VERSION_1_3     = 0x03,
-  CEC_VERSION_1_3A    = 0x04
+  CEC_VERSION_1_3A    = 0x04,
+  CEC_VERSION_1_4     = 0x05
 } cec_version;
 
 typedef enum cec_channel_identifier
@@ -816,30 +817,6 @@ typedef enum cec_vendor_id
   CEC_VENDOR_UNKNOWN   = 0
 } cec_vendor_id;
 
-typedef struct cec_vendor
-{
-#ifdef __cplusplus
-  const char *AsString(void) const
-  {
-    switch (vendor)
-    {
-    case CEC_VENDOR_SAMSUNG:
-      return "Samsung";
-    case CEC_VENDOR_LG:
-      return "LG";
-    case CEC_VENDOR_PANASONIC:
-      return "Panasonic";
-    case CEC_VENDOR_PIONEER:
-      return "Pioneer";
-    default:
-      return "Unknown";
-    }
-  }
-#endif
-
-  cec_vendor_id vendor;
-} cec_vendor;
-
 //default physical address 1.0.0.0, HDMI port 1
 #define CEC_DEFAULT_PHYSICAL_ADDRESS 0x1000
 #define MSGSTART                     0xFF
index d094be1341b943d967fd7d598191b5247407642a..cf3ea3f39631b9b71daf41697658fd843acfae78 100644 (file)
@@ -157,7 +157,8 @@ bool CCECProcessor::TryLogicalAddress(cec_logical_address address, unsigned int
       m_busDevices[address]->m_bActiveSource = true;
     }
     m_busDevices[address]->m_powerStatus = CEC_POWER_STATUS_STANDBY;
-    m_busDevices[address]->m_cecVersion = CEC_VERSION_1_3A;
+    m_busDevices[address]->m_cecVersion =  CEC_VERSION_1_3A;
+
     m_logicalAddresses.set(address);
 
     // TODO
index f2c0fad14bc388ef73dad5d6e5a0a7492b66a837..d6c6f70d53d99f1960b3bf9ab20bf863945fc268 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "CECAudioSystem.h"
 #include "../CECProcessor.h"
+#include "../implementations/CECCommandHandler.h"
 
 using namespace CEC;
 
@@ -40,14 +41,44 @@ CCECAudioSystem::CCECAudioSystem(CCECProcessor *processor, cec_logical_address a
     m_systemAudioStatus(CEC_SYSTEM_AUDIO_STATUS_ON),
     m_audioStatus(CEC_AUDIO_MUTE_STATUS_MASK)
 {
-  m_type          = CEC_DEVICE_TYPE_AUDIO_SYSTEM;
+  m_type = CEC_DEVICE_TYPE_AUDIO_SYSTEM;
+}
+
+bool CCECAudioSystem::SetAudioStatus(const cec_audio_status status)
+{
+  if (m_audioStatus != status)
+  {
+    CStdString strLog;
+    strLog.Format(">> %s (%X): audio status changed from %s to %s", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(m_audioStatus), CCECCommandHandler::ToString(status));
+    AddLog(CEC_LOG_DEBUG, strLog.c_str());
+
+    m_audioStatus = status;
+    return true;
+  }
+
+  return false;
+}
+
+bool CCECAudioSystem::SetSystemAudioMode(const cec_system_audio_status mode)
+{
+  if (m_systemAudioStatus != mode)
+  {
+    CStdString strLog;
+    strLog.Format(">> %s (%X): system audio mode changed from %s to %s", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(m_systemAudioStatus), CCECCommandHandler::ToString(mode));
+    AddLog(CEC_LOG_DEBUG, strLog.c_str());
+
+    m_systemAudioStatus = mode;
+    return true;
+  }
+
+  return false;
 }
 
 bool CCECAudioSystem::SetSystemAudioMode(const cec_command &command)
 {
-  m_systemAudioStatus = (command.parameters.size == 0) ?
+  SetSystemAudioMode((command.parameters.size == 0) ?
     CEC_SYSTEM_AUDIO_STATUS_OFF :
-  CEC_SYSTEM_AUDIO_STATUS_ON;
+  CEC_SYSTEM_AUDIO_STATUS_ON);
 
   return TransmitAudioStatus(command.initiator);
 }
@@ -55,7 +86,7 @@ bool CCECAudioSystem::SetSystemAudioMode(const cec_command &command)
 bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %x -> %x: audio status '%2x'", m_iLogicalAddress, dest, m_audioStatus);
+  strLog.Format("<< %x -> %x: audio status '%2x'", m_iLogicalAddress, dest, CCECCommandHandler::ToString(m_audioStatus));
   AddLog(CEC_LOG_NOTICE, strLog);
 
   cec_command command;
@@ -68,7 +99,7 @@ bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest)
 bool CCECAudioSystem::TransmitSystemAudioModeStatus(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %x -> %x: system audio mode '%2x'", m_iLogicalAddress, dest, m_systemAudioStatus);
+  strLog.Format("<< %x -> %x: system audio mode '%s'", m_iLogicalAddress, dest, CCECCommandHandler::ToString(m_systemAudioStatus));
   AddLog(CEC_LOG_NOTICE, strLog);
 
   cec_command command;
index 56b73a110acadca3e8e80770aac37e3d58565cfe..0a80dacf60146cca8249cd37f06fa4bde7a39c89 100644 (file)
@@ -41,6 +41,8 @@ namespace CEC
     CCECAudioSystem(CCECProcessor *processor, cec_logical_address address, uint16_t iPhysicalAddress = 0);
     virtual ~CCECAudioSystem(void) {};
 
+    virtual bool SetAudioStatus(const cec_audio_status status);
+    virtual bool SetSystemAudioMode(const cec_system_audio_status mode);
     virtual bool SetSystemAudioMode(const cec_command &command);
     virtual bool TransmitAudioStatus(cec_logical_address dest);
     virtual bool TransmitSystemAudioModeStatus(cec_logical_address dest);
index dc6d4f8832c1ff477d74244279cd5f334a01a65d..3eeb295af5a34ba2c3ab5b6ec8f754a0c0fc6305 100644 (file)
 
 using namespace CEC;
 
+#define ToString(p) CCECCommandHandler::ToString(p)
+
 CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress) :
+  m_type(CEC_DEVICE_TYPE_RESERVED),
   m_iPhysicalAddress(iPhysicalAddress),
   m_iStreamPath(0),
   m_iLogicalAddress(iLogicalAddress),
   m_powerStatus(CEC_POWER_STATUS_UNKNOWN),
   m_processor(processor),
+  m_vendor(CEC_VENDOR_UNKNOWN),
   m_bMenuActive(true),
   m_bActiveSource(false),
-  m_iVendorClass(CEC_VENDOR_UNKNOWN),
   m_iLastCommandSent(0),
   m_iLastActive(0),
   m_cecVersion(CEC_VERSION_UNKNOWN)
@@ -60,9 +63,7 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi
   m_menuLanguage.language[3] = 0;
   m_menuLanguage.device = iLogicalAddress;
 
-  m_vendor.vendor = CEC_VENDOR_UNKNOWN;
-  m_type          = CEC_DEVICE_TYPE_RESERVED;
-  m_strDeviceName = CCECCommandHandler::ToString(m_iLogicalAddress);
+  m_strDeviceName = ToString(m_iLogicalAddress);
 }
 
 CCECBusDevice::~CCECBusDevice(void)
@@ -89,7 +90,7 @@ void CCECBusDevice::PollVendorId(void)
 {
   CLockObject lock(&m_mutex);
   if (m_iLastActive > 0 && m_iLogicalAddress != CECDEVICE_BROADCAST &&
-      m_vendor.vendor == CEC_VENDOR_UNKNOWN &&
+      m_vendor == CEC_VENDOR_UNKNOWN &&
       GetTimeMs() - m_iLastCommandSent > 5000 &&
       !m_processor->IsMonitoring())
   {
@@ -162,7 +163,7 @@ cec_version CCECBusDevice::GetCecVersion(void)
 
 const char* CCECBusDevice::GetLogicalAddressName(void) const
 {
-  return CCECCommandHandler::ToString(m_iLogicalAddress);
+  return ToString(m_iLogicalAddress);
 }
 
 cec_menu_language &CCECBusDevice::GetMenuLanguage(void)
@@ -215,9 +216,9 @@ cec_power_status CCECBusDevice::GetPowerStatus(void)
   return m_powerStatus;
 }
 
-const cec_vendor &CCECBusDevice::GetVendor(void)
+const cec_vendor_id CCECBusDevice::GetVendorId(void)
 {
-  if (m_vendor.vendor == CEC_VENDOR_UNKNOWN)
+  if (m_vendor == CEC_VENDOR_UNKNOWN)
   {
     if (!MyLogicalAddressContains(m_iLogicalAddress))
     {
@@ -236,6 +237,12 @@ const cec_vendor &CCECBusDevice::GetVendor(void)
   return m_vendor;
 }
 
+const char *CCECBusDevice::GetVendorName(void)
+{
+  GetVendorId();
+  return ToString(m_vendor);
+}
+
 bool CCECBusDevice::MyLogicalAddressContains(cec_logical_address address) const
 {
   return m_processor->HasLogicalAddress(address);
@@ -250,7 +257,7 @@ void CCECBusDevice::SetCecVersion(const cec_version newVersion)
   m_cecVersion = newVersion;
 
   CStdString strLog;
-  strLog.Format("%s (%X): CEC version %s", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(newVersion));
+  strLog.Format("%s (%X): CEC version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(newVersion));
   AddLog(CEC_LOG_DEBUG, strLog);
 }
 
@@ -297,16 +304,15 @@ void CCECBusDevice::SetPowerStatus(const cec_power_status powerStatus)
   if (m_powerStatus != powerStatus)
   {
     CStdString strLog;
-    strLog.Format(">> %s (%X): power status changed from '%s' to '%s'", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(m_powerStatus), CCECCommandHandler::ToString(powerStatus));
+    strLog.Format(">> %s (%X): power status changed from '%s' to '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_powerStatus), ToString(powerStatus));
     m_processor->AddLog(CEC_LOG_DEBUG, strLog);
     m_powerStatus = powerStatus;
   }
 }
 
-void CCECBusDevice::SetVendorId(uint64_t iVendorId, uint8_t iVendorClass /* = 0 */)
+void CCECBusDevice::SetVendorId(uint64_t iVendorId)
 {
-  m_vendor.vendor = (cec_vendor_id)iVendorId;
-  m_iVendorClass = iVendorClass;
+  m_vendor = (cec_vendor_id)iVendorId;
 
   switch (iVendorId)
   {
@@ -341,7 +347,7 @@ void CCECBusDevice::SetVendorId(uint64_t iVendorId, uint8_t iVendorClass /* = 0
   }
 
   CStdString strLog;
-  strLog.Format("%s (%X): vendor = %s (%06x) class = %2x", GetLogicalAddressName(), m_iLogicalAddress, GetVendorName(), GetVendorId(), GetVendorClass());
+  strLog.Format("%s (%X): vendor = %s (%06x)", GetLogicalAddressName(), m_iLogicalAddress, GetVendorName(), GetVendorId());
   m_processor->AddLog(CEC_LOG_DEBUG, strLog.c_str());
 }
 //@}
@@ -382,7 +388,7 @@ bool CCECBusDevice::TransmitActiveSource(void)
 bool CCECBusDevice::TransmitCECVersion(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): cec version %s", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest, CCECCommandHandler::ToString(m_cecVersion));
+  strLog.Format("<< %s (%X) -> %s (%X): cec version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_cecVersion));
   AddLog(CEC_LOG_NOTICE, strLog);
 
   cec_command command;
@@ -409,7 +415,7 @@ bool CCECBusDevice::TransmitInactiveView(void)
 bool CCECBusDevice::TransmitMenuState(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): ", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest);
+  strLog.Format("<< %s (%X) -> %s (%X): ", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
   if (m_bMenuActive)
     strLog.append("menu active");
   else
@@ -426,7 +432,7 @@ bool CCECBusDevice::TransmitMenuState(cec_logical_address dest)
 bool CCECBusDevice::TransmitOSDName(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): OSD name '%s'", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest, m_strDeviceName.c_str());
+  strLog.Format("<< %s (%X) -> %s (%X): OSD name '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, m_strDeviceName.c_str());
   AddLog(CEC_LOG_NOTICE, strLog.c_str());
 
   cec_command command;
@@ -440,7 +446,7 @@ bool CCECBusDevice::TransmitOSDName(cec_logical_address dest)
 bool CCECBusDevice::TransmitOSDString(cec_logical_address dest, cec_display_control duration, const char *strMessage)
 {
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest, strMessage);
+  strLog.Format("<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, strMessage);
   AddLog(CEC_LOG_NOTICE, strLog.c_str());
 
   cec_command command;
@@ -479,7 +485,7 @@ bool CCECBusDevice::TransmitPoll(cec_logical_address dest)
     dest = m_iLogicalAddress;
 
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest);
+  strLog.Format("<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
   AddLog(CEC_LOG_NOTICE, strLog.c_str());
 
   cec_command command;
@@ -494,7 +500,7 @@ bool CCECBusDevice::TransmitPoll(cec_logical_address dest)
 bool CCECBusDevice::TransmitPowerState(cec_logical_address dest)
 {
   CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): %s", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest, CCECCommandHandler::ToString(m_powerStatus));
+  strLog.Format("<< %s (%X) -> %s (%X): %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_powerStatus));
   AddLog(CEC_LOG_NOTICE, strLog.c_str());
 
   cec_command command;
@@ -506,11 +512,29 @@ bool CCECBusDevice::TransmitPowerState(cec_logical_address dest)
 
 bool CCECBusDevice::TransmitVendorID(cec_logical_address dest)
 {
-  CStdString strLog;
-  strLog.Format("<< %s (%X) -> %s (%X): vendor id feature abort", GetLogicalAddressName(), m_iLogicalAddress, CCECCommandHandler::ToString(dest), dest);
-  AddLog(CEC_LOG_NOTICE, strLog);
+  if (m_vendor == CEC_VENDOR_UNKNOWN)
+  {
+    CStdString strLog;
+    strLog.Format("<< %s (%X) -> %s (%X): vendor id feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
+    AddLog(CEC_LOG_NOTICE, strLog);
 
-  m_processor->TransmitAbort(dest, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
-  return false;
+    m_processor->TransmitAbort(dest, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
+    return false;
+  }
+  else
+  {
+    CStdString strLog;
+    strLog.Format("<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_vendor), (uint64_t)m_vendor);
+    AddLog(CEC_LOG_NOTICE, strLog);
+
+    cec_command command;
+    cec_command::format(command, m_iLogicalAddress, dest, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
+
+    command.parameters.push_back((uint8_t) (((uint64_t)m_vendor >> 16) & 0xFF));
+    command.parameters.push_back((uint8_t) (((uint64_t)m_vendor >> 8) & 0xFF));
+    command.parameters.push_back((uint8_t) ((uint64_t)m_vendor & 0xFF));
+
+    return m_processor->Transmit(command);
+  }
 }
 //@}
index d07f4c8ab921b6a9b60218d5db4f1f535d160212..cad65911008a87a62ece20ce28612c04cf74bbec 100644 (file)
@@ -67,17 +67,15 @@ namespace CEC
     virtual cec_power_status    GetPowerStatus(void);
     virtual CCECProcessor *     GetProcessor(void) const { return m_processor; }
     virtual cec_device_type     GetType(void) const { return m_type; }
-    virtual const cec_vendor &  GetVendor(void);
-    virtual uint8_t             GetVendorClass(void) const { return m_iVendorClass; }
-    virtual cec_vendor_id       GetVendorId(void) { return GetVendor().vendor; };
-    virtual const char *        GetVendorName(void) { return GetVendor().AsString(); }
+    virtual const cec_vendor_id GetVendorId(void);
+    virtual const char *        GetVendorName(void);
     virtual bool                MyLogicalAddressContains(cec_logical_address address) const;
 
     virtual void SetPhysicalAddress(uint16_t iNewAddress);
     virtual void SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress = 0);
     virtual void SetCecVersion(const cec_version newVersion);
     virtual void SetMenuLanguage(const cec_menu_language &menuLanguage);
-    virtual void SetVendorId(uint64_t iVendorId, uint8_t iVendorClass = 0);
+    virtual void SetVendorId(uint64_t iVendorId);
     virtual void SetPowerStatus(const cec_power_status powerStatus);
 
     virtual bool TransmitActiveSource(void);
@@ -101,10 +99,9 @@ namespace CEC
     cec_menu_language   m_menuLanguage;
     CCECProcessor      *m_processor;
     CCECCommandHandler *m_handler;
-    cec_vendor          m_vendor;
+    cec_vendor_id       m_vendor;
     bool                m_bMenuActive;
     bool                m_bActiveSource;
-    uint8_t             m_iVendorClass;
     uint64_t            m_iLastCommandSent;
     uint64_t            m_iLastActive;
     cec_version         m_cecVersion;
index 7785ef64091670b0da52fd78c45e76dfb1a3801e..1c0f8d95ed81ce53184a1efd0f717996cf79fd86 100644 (file)
@@ -212,6 +212,7 @@ bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command)
 bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
 {
   SetVendorId(command);
+  m_busDevice->GetProcessor()->TransmitAbort(command.initiator, command.opcode, CEC_ABORT_REASON_REFUSED);
   return true;
 }
 
@@ -315,6 +316,7 @@ bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command)
   vector<CCECBusDevice *> devices;
   for (int iDevicePtr = (int)GetMyDevices(devices)-1; iDevicePtr >=0; iDevicePtr--)
     devices[iDevicePtr]->TransmitActiveSource();
+
   return true;
 }
 
@@ -463,6 +465,11 @@ CCECBusDevice *CCECCommandHandler::GetDeviceByPhysicalAddress(uint16_t iPhysical
   return m_busDevice->GetProcessor()->GetDeviceByPhysicalAddress(iPhysicalAddress);
 }
 
+CCECBusDevice *CCECCommandHandler::GetDeviceByType(cec_device_type type) const
+{
+  return m_busDevice->GetProcessor()->GetDeviceByType(type);
+}
+
 void CCECCommandHandler::SetVendorId(const cec_command &command)
 {
   if (command.parameters.size < 3)
@@ -477,7 +484,7 @@ void CCECCommandHandler::SetVendorId(const cec_command &command)
 
   CCECBusDevice *device = GetDevice((cec_logical_address) command.initiator);
   if (device)
-    device->SetVendorId(iVendorId, command.parameters.size > 3 ? command.parameters[3] : 0);
+    device->SetVendorId(iVendorId);
 }
 
 const char *CCECCommandHandler::ToString(const cec_version version)
@@ -492,6 +499,8 @@ const char *CCECCommandHandler::ToString(const cec_version version)
     return "1.3";
   case CEC_VERSION_1_3A:
     return "1.3a";
+  case CEC_VERSION_1_4:
+    return "1.4";
   default:
     return "unknown";
   }
@@ -743,3 +752,39 @@ const char *CCECCommandHandler::ToString(const cec_opcode opcode)
     return "UNKNOWN";
   }
 }
+
+const char *CCECCommandHandler::ToString(const cec_system_audio_status mode)
+{
+  switch(mode)
+  {
+  case CEC_SYSTEM_AUDIO_STATUS_ON:
+    return "on";
+  case CEC_SYSTEM_AUDIO_STATUS_OFF:
+    return "off";
+  default:
+    return "unknown";
+  }
+}
+
+const char *CCECCommandHandler::ToString(const cec_audio_status status)
+{
+  // TODO this is a mask
+  return "TODO";
+}
+
+const char *CCECCommandHandler::ToString(const cec_vendor_id vendor)
+{
+  switch (vendor)
+  {
+  case CEC_VENDOR_SAMSUNG:
+    return "Samsung";
+  case CEC_VENDOR_LG:
+    return "LG";
+  case CEC_VENDOR_PANASONIC:
+    return "Panasonic";
+  case CEC_VENDOR_PIONEER:
+    return "Pioneer";
+  default:
+    return "Unknown";
+  }
+}
index 16095f649dd8ff0e10bbfee10d5686d64999a6c4..aed84fdfd816f69552c3e1d6369e64bf5f2dff4e 100644 (file)
@@ -53,6 +53,9 @@ namespace CEC
     static const char *ToString(const cec_deck_info status);
     static const char* ToString(const cec_logical_address address);
     static const char* ToString(const cec_opcode opcode);
+    static const char *ToString(const cec_system_audio_status mode);
+    static const char *ToString(const cec_audio_status status);
+    static const char *ToString(const cec_vendor_id vendor);
 
   protected:
     virtual bool HandleActiveSource(const cec_command &command);
@@ -83,6 +86,7 @@ namespace CEC
     virtual unsigned int GetMyDevices(std::vector<CCECBusDevice *> &devices) const;
     virtual CCECBusDevice *GetDevice(cec_logical_address iLogicalAddress) const;
     virtual CCECBusDevice *GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress) const;
+    virtual CCECBusDevice *GetDeviceByType(cec_device_type type) const;
 
     virtual void SetVendorId(const cec_command &command);
     CCECBusDevice *m_busDevice;