From e55f3f703996f8c347db3fe2442893163f5523b7 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sun, 30 Oct 2011 14:31:22 +0100 Subject: [PATCH] cec: added GetDevicePowerStatus()/cec_get_device_power_status() --- include/cec.h | 5 +++ include/cecc.h | 11 +++++++ include/cectypes.h | 7 ++-- src/lib/CECProcessor.cpp | 5 +++ src/lib/CECProcessor.h | 1 + src/lib/LibCEC.cpp | 6 ++++ src/lib/LibCEC.h | 1 + src/lib/LibCECC.cpp | 7 ++++ src/lib/devices/CECBusDevice.cpp | 26 ++++++++++++++- src/lib/devices/CECBusDevice.h | 5 ++- src/lib/implementations/CECCommandHandler.cpp | 15 ++++++++- src/lib/implementations/CECCommandHandler.h | 1 + src/testclient/main.cpp | 33 +++++++++++++++++++ 13 files changed, 117 insertions(+), 6 deletions(-) diff --git a/include/cec.h b/include/cec.h index 4389d7b..1701df7 100644 --- a/include/cec.h +++ b/include/cec.h @@ -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; }; }; diff --git a/include/cecc.h b/include/cecc.h index 0c9d57c..bec3920 100644 --- a/include/cecc.h +++ b/include/cecc.h @@ -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 diff --git a/include/cectypes.h b/include/cectypes.h index 2ae9043..53418ab 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -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 { diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index eea66ee..38eb5cd 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -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); diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 025d6dd..6b663e3 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -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; diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index d7d7d60..ed60f43 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -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) { diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index 286e47e..391148d 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -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); diff --git a/src/lib/LibCECC.cpp b/src/lib/LibCECC.cpp index ad663b7..28a268b 100644 --- a/src/lib/LibCECC.cpp +++ b/src/lib/LibCECC.cpp @@ -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; +} + //@} diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index f26e7c3..c798ded 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -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) diff --git a/src/lib/devices/CECBusDevice.h b/src/lib/devices/CECBusDevice.h index 81d5796..db89f40 100644 --- a/src/lib/devices/CECBusDevice.h +++ b/src/lib/devices/CECBusDevice.h @@ -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; diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 0607acd..277f756 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -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) diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index 4eff901..e7184df 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -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); diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index 38f6b5b..33cbd88 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -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; -- 2.34.1