cec: added GetDevicePowerStatus()/cec_get_device_power_status()
authorLars Op den Kamp <lars@opdenkamp.eu>
Sun, 30 Oct 2011 13:31:22 +0000 (14:31 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sun, 30 Oct 2011 13:31:22 +0000 (14:31 +0100)
13 files changed:
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/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/CECCommandHandler.h
src/testclient/main.cpp

index 4389d7bfa849101c86250265952b1b74f94202bb..1701df786c16fe7489e356cf76e3ed157ded3f32 100644 (file)
@@ -154,6 +154,11 @@ namespace CEC
      * @see cec_get_device_vendor_id
      */
     virtual uint64_t GetDeviceVendorId(cec_logical_address iAddress) = 0;
+
+    /*!
+     * @see cec_get_device_power_status
+     */
+    virtual cec_power_status GetDevicePowerStatus(cec_logical_address iAddress) = 0;
   };
 };
 
index 0c9d57ce2769a5fa3ebe2f90b74d4e6a5ce91298..bec392030e6cd67bce5443ed4f7aa3540efdcac7 100644 (file)
@@ -255,6 +255,17 @@ 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
 
+/*!
+ * @brief Get the power status of the device with the given logical address.
+ * @param iLogicalAddress The device to get the power status for.
+ * @return The power status or CEC_POWER_STATUS_UNKNOWN if it wasn't found.
+ */
+#ifdef __cplusplus
+extern DECLSPEC CEC::cec_power_status cec_get_device_power_status(CEC::cec_logical_address iLogicalAddress);
+#else
+extern DECLSPEC cec_power_status cec_get_device_power_status(cec_logical_address iLogicalAddress);
+#endif
+
 #ifdef __cplusplus
 };
 #endif
index 2ae9043e6d1824605e893a8e59e44d2bd3f71407..53418abded9421f71b411d641ca31e33d28febf8 100644 (file)
@@ -198,13 +198,14 @@ typedef enum
   CEC_PLAY_MODE_SLOW_REVERSE_MAX_SPEED = 0x1B
 } ECecPlayMode;
 
-typedef enum
+typedef enum cec_power_status
 {
   CEC_POWER_STATUS_ON = 0x00,
   CEC_POWER_STATUS_STANDBY = 0x01,
   CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON = 0x02,
-  CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY = 0x03
-} ECecPowerStatus;
+  CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY = 0x03,
+  CEC_POWER_STATUS_UNKNOWN = 0x99
+} cec_power_status;
 
 typedef enum
 {
index eea66ee1e638d268e0ec682a5f2a6df70deb2e26..38eb5cdce7cd55631c2e44f7ef7487ae344b1e2a 100644 (file)
@@ -218,6 +218,11 @@ uint64_t CCECProcessor::GetDeviceVendorId(cec_logical_address iAddress)
   return m_busDevices[iAddress]->GetVendorId();
 }
 
+cec_power_status CCECProcessor::GetDevicePowerStatus(cec_logical_address iAddress)
+{
+  return m_busDevices[iAddress]->GetPowerStatus();
+}
+
 bool CCECProcessor::Transmit(const cec_command &data)
 {
   bool bReturn(false);
index 025d6dd26c7871b7814ac4ffbe7c4b3fbbdc08de..6b663e352f04de9e7d3a00321493f6fd4bb06f30 100644 (file)
@@ -64,6 +64,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 cec_power_status GetDevicePowerStatus(cec_logical_address iAddress);
 
       virtual cec_logical_address GetLogicalAddress(void) const { return m_iLogicalAddress; }
       virtual uint16_t GetPhysicalAddress(void) const;
index d7d7d60655b35108a9c4a4502bed163582e19fdb..ed60f43ff2f25f623e814f86b282c781c5f0e915 100644 (file)
@@ -225,6 +225,12 @@ uint64_t CLibCEC::GetDeviceVendorId(cec_logical_address iAddress)
   return 0;
 }
 
+cec_power_status CLibCEC::GetDevicePowerStatus(cec_logical_address iAddress)
+{
+  if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
+    return m_cec->GetDevicePowerStatus(iAddress);
+  return CEC_POWER_STATUS_UNKNOWN;
+}
 
 void CLibCEC::AddLog(cec_log_level level, const string &strMessage)
 {
index 286e47e0569f480980e1a248c0b4f7302d8b3831..391148dadbf110bfb93c993ff6e9b187bf3062f1 100644 (file)
@@ -76,6 +76,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 cec_power_status GetDevicePowerStatus(cec_logical_address iAddress);
     //@}
 
       virtual void AddLog(cec_log_level level, const std::string &strMessage);
index ad663b7623fcf104e528f0fa5bab7c5b3a054c74..28a268b3879532f263c55095da3f3efae6553b18 100644 (file)
@@ -208,4 +208,11 @@ uint64_t cec_get_device_vendor_id(cec_logical_address iLogicalAddress)
   return 0;
 }
 
+cec_power_status cec_get_device_power_status(cec_logical_address iLogicalAddress)
+{
+  if (cec_parser)
+    return cec_parser->GetDevicePowerStatus(iLogicalAddress);
+  return CEC_POWER_STATUS_UNKNOWN;
+}
+
 //@}
index f26e7c3c456765f40ef3786b952e6caa14f4f127..c798ded339e365fb1dc2f094fc1e674487144cdd 100644 (file)
@@ -42,6 +42,7 @@ using namespace CEC;
 CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress) :
   m_iPhysicalAddress(iPhysicalAddress),
   m_iLogicalAddress(iLogicalAddress),
+  m_powerStatus(CEC_POWER_STATUS_UNKNOWN),
   m_processor(processor),
   m_iVendorId(0),
   m_iVendorClass(CEC_VENDOR_UNKNOWN),
@@ -87,7 +88,7 @@ void CCECBusDevice::SetMenuLanguage(const cec_menu_language &language)
   }
 }
 
-void CCECBusDevice::SetCecVersion(cec_version newVersion)
+void CCECBusDevice::SetCecVersion(const cec_version newVersion)
 {
   CStdString strLog;
   m_cecVersion = newVersion;
@@ -114,6 +115,14 @@ void CCECBusDevice::SetCecVersion(cec_version newVersion)
   AddLog(CEC_LOG_DEBUG, strLog);
 }
 
+void CCECBusDevice::SetPowerStatus(const cec_power_status powerStatus)
+{
+  CStdString strLog;
+  strLog.Format("device %d power status changed from %2x to %2x", m_iLogicalAddress, m_powerStatus, powerStatus);
+  m_processor->AddLog(CEC_LOG_DEBUG, strLog);
+  m_powerStatus = powerStatus;
+}
+
 void CCECBusDevice::SetVendorId(const cec_datapacket &data)
 {
   if (data.size < 3)
@@ -404,6 +413,21 @@ cec_menu_language &CCECBusDevice::GetMenuLanguage(void)
   return m_menuLanguage;
 }
 
+cec_power_status CCECBusDevice::GetPowerStatus(void)
+{
+  if (m_powerStatus == CEC_POWER_STATUS_UNKNOWN)
+  {
+    AddLog(CEC_LOG_NOTICE, "<< requesting power status");
+    cec_command command;
+    cec_command::format(command, GetMyLogicalAddress(), m_iLogicalAddress, CEC_OPCODE_GIVE_DEVICE_POWER_STATUS);
+    CLockObject lock(&m_mutex);
+    if (m_processor->Transmit(command))
+      m_condition.Wait(&m_mutex, 1000);
+  }
+
+  return m_powerStatus;
+}
+
 const char *CCECBusDevice::CECVendorIdToString(const uint64_t iVendorId)
 {
   switch (iVendorId)
index 81d5796604515233e9f31ec084d9dbfa8bf8c22d..db89f40bc5571eeac20ba6e3540818d398b1f66f 100644 (file)
@@ -56,6 +56,7 @@ namespace CEC
     virtual uint16_t            GetPhysicalAddress(void) const { return m_iPhysicalAddress; }
     virtual cec_version         GetCecVersion(void);
     virtual cec_menu_language & GetMenuLanguage(void);
+    virtual cec_power_status    GetPowerStatus(void);
 
     virtual bool PowerOn(void);
     virtual bool Standby(void);
@@ -63,10 +64,11 @@ namespace CEC
     virtual void PollVendorId(void);
 
     virtual void SetPhysicalAddress(uint16_t iNewAddress, uint16_t iOldAddress = 0);
-    virtual void SetCecVersion(cec_version newVersion);
+    virtual void SetCecVersion(const cec_version newVersion);
     virtual void SetMenuLanguage(const cec_menu_language &menuLanguage);
     virtual void SetVendorId(const cec_datapacket &data);
     virtual void SetVendorId(uint64_t iVendorId, uint8_t iVendorClass = 0);
+    virtual void SetPowerStatus(const cec_power_status powerStatus);
 
     virtual bool HandleCommand(const cec_command &command);
 
@@ -91,6 +93,7 @@ namespace CEC
   protected:
     uint16_t            m_iPhysicalAddress;
     cec_logical_address m_iLogicalAddress;
+    cec_power_status    m_powerStatus;
     cec_menu_language   m_menuLanguage;
     CCECProcessor      *m_processor;
     CCECCommandHandler *m_handler;
index 0607acd4573f89a4874bd3ceaa92967aac6c1355..277f75624674b55d74156bd339e40f2a6bc8a616 100644 (file)
@@ -49,6 +49,9 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command)
   {
     switch(command.opcode)
     {
+    case CEC_OPCODE_REPORT_POWER_STATUS:
+      HandleReportPowerStatus(command);
+      break;
     case CEC_OPCODE_CEC_VERSION:
       HandleDeviceCecVersion(command);
       break;
@@ -233,6 +236,17 @@ bool CCECCommandHandler::HandleMenuRequest(const cec_command &command)
   return false;
 }
 
+bool CCECCommandHandler::HandleReportPowerStatus(const cec_command &command)
+{
+  if (command.parameters.size == 1)
+  {
+    CCECBusDevice *device = GetDevice(command.initiator);
+    if (device)
+      device->SetPowerStatus((cec_power_status) command.parameters[0]);
+  }
+  return true;
+}
+
 bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command)
 {
   CStdString strLog;
@@ -276,7 +290,6 @@ bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command)
   return true;
 }
 
-
 bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
 {
   if (command.parameters.size >= 2)
index 4eff90192db73d047bef378335168c316e63a6ef..e7184dfc8d708836acd22e8d731e36c2d105541d 100644 (file)
@@ -57,6 +57,7 @@ namespace CEC
     bool HandleGiveOSDName(const cec_command &command);
     bool HandleGivePhysicalAddress(const cec_command &command);
     bool HandleMenuRequest(const cec_command &command);
+    bool HandleReportPowerStatus(const cec_command &command);
     bool HandleRequestActiveSource(const cec_command &command);
     bool HandleRoutingChange(const cec_command &command);
     bool HandleSetMenuLanguage(const cec_command &command);
index 38f6b5bd8eaaba8832890680da9e27d7325a827f..33cbd88e2cec3ebec16cf97394061723a40ea14a 100644 (file)
@@ -227,6 +227,9 @@ void show_console_help(void)
   "lang {addr}               get the menu language of the specified device." << endl <<
   "[lang 0]                  get the menu language of the TV" << endl <<
   endl <<
+  "pow {addr}                get the power status of the specified device." << endl <<
+  "[pow 0]                   get the power status of the TV" << endl <<
+  endl <<
   "[mon] {1|0}               enable or disable CEC bus monitoring." << endl <<
   "[log] {1 - 31}            change the log level. see cectypes.h for values." << endl <<
   "[ping]                    send a ping command to the CEC adapter." << endl <<
@@ -565,6 +568,36 @@ int main (int argc, char *argv[])
             }
           }
         }
+        else if (command == "pow")
+        {
+          CStdString strDev;
+          if (GetWord(input, strDev))
+          {
+            int iDev = atoi(strDev);
+            if (iDev >= 0 && iDev < 15)
+            {
+              cec_power_status iPower = parser->GetDevicePowerStatus((cec_logical_address) iDev);
+              switch (iPower)
+              {
+              case CEC_POWER_STATUS_ON:
+                cout << "powered on" << endl;
+                break;
+              case CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY:
+                cout << "on -> standby" << endl;
+                break;
+              case CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON:
+                cout << "standby -> on" << endl;
+                break;
+              case CEC_POWER_STATUS_STANDBY:
+                cout << "standby" << endl;
+                break;
+              default:
+                cout << "unknown power status" << endl;
+                break;
+              }
+            }
+          }
+        }
         else if (command == "r")
         {
           cout << "closing the connection" << endl;