* @see cec_switch_monitoring
*/
virtual bool SwitchMonitoring(bool bEnable) = 0;
+
+ /*!
+ * @see cec_get_device_cec_version
+ */
+ virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress) = 0;
};
};
extern DECLSPEC int cec_set_physical_address(uint16_t iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS);
/*!
- * @brief Display a message on the TV.
- * @brief The message to display.
+ * @brief Display a message on the device with the given logical address.
+ * @param iLogicalAddres The device to display the message on.
+ * @param duration The duration of the message
+ * @param strMessage The message to display.
* @return True when the command was sent, false otherwise.
*/
#ifdef __cplusplus
extern DECLSPEC int cec_set_osd_string(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage);
#endif
+/*!
+ * @brief Enable or disable monitoring mode.
+ * @param bEnable True to enable, false to disable.
+ * @return True when switched successfully, false otherwise.
+ */
extern DECLSPEC int cec_switch_monitoring(int bEnable);
+/*!
+ * @brief Get the CEC version of the device with the given logical address
+ * @param iLogicalAddress The device to get the CEC version for.
+ * @return The version or CEC_VERSION_UNKNOWN when the version couldn't be fetched.
+ */
+#ifdef __cplusplus
+extern DECLSPEC CEC::cec_version cec_get_device_cec_version(CEC::cec_logical_address iLogicalAddress);
+#else
+extern DECLSPEC cec_version cec_get_device_cec_version(cec_logical_address iLogicalAddress);
+#endif
+
#ifdef __cplusplus
};
#endif
CEC_TRUE = 1
} ECecBoolean;
-typedef enum
-{
- CEC_VERSION_1_2 = 0x01,
- CEC_VERSION_1_2A = 0x02,
- CEC_VERSION_1_3 = 0x03,
- CEC_VERSION_1_3A = 0x04
-} ECecVersion;
+typedef enum cec_version
+{
+ CEC_VERSION_UNKNOWN = 0x00,
+ CEC_VERSION_1_2 = 0x01,
+ CEC_VERSION_1_2A = 0x02,
+ CEC_VERSION_1_3 = 0x03,
+ CEC_VERSION_1_3A = 0x04
+} cec_version;
typedef enum
{
return m_communication && m_communication->SetAckMask(0x1 << (uint8_t)m_iLogicalAddress);
}
+cec_version CCECProcessor::GetDeviceCecVersion(cec_logical_address iAddress)
+{
+ return m_busDevices[iAddress]->GetCecVersion();
+}
+
bool CCECProcessor::Transmit(const cec_command &data)
{
bool bReturn(false);
virtual bool SetLogicalAddress(cec_logical_address iLogicalAddress);
virtual bool SetPhysicalAddress(uint16_t iPhysicalAddress);
virtual bool SwitchMonitoring(bool bEnable);
+ virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress);
virtual cec_logical_address GetLogicalAddress(void) const { return m_iLogicalAddress; }
virtual uint16_t GetPhysicalAddress(void) const;
return m_cec ? m_cec->SwitchMonitoring(bEnable) : false;
}
+cec_version CLibCEC::GetDeviceCecVersion(cec_logical_address iAddress)
+{
+ if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
+ return m_cec->GetDeviceCecVersion(iAddress);
+ return CEC_VERSION_UNKNOWN;
+}
+
void CLibCEC::AddLog(cec_log_level level, const string &strMessage)
{
if (m_cec)
virtual bool SetInactiveView(void);
virtual bool SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage);
virtual bool SwitchMonitoring(bool bEnable);
+ virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress);
//@}
virtual void AddLog(cec_log_level level, const std::string &strMessage);
return -1;
}
+cec_version cec_get_device_cec_version(cec_logical_address iLogicalAddress)
+{
+ if (cec_parser)
+ return cec_parser->GetDeviceCecVersion(iLogicalAddress);
+ return CEC_VERSION_UNKNOWN;
+}
+
//@}
m_processor(processor),
m_iVendorId(0),
m_iVendorClass(CEC_VENDOR_UNKNOWN),
- m_iLastActive(0)
+ m_iLastActive(0),
+ m_cecVersion(CEC_VERSION_UNKNOWN)
{
m_handler = new CCECCommandHandler(this);
}
CCECBusDevice::~CCECBusDevice(void)
{
+ m_condition.Broadcast();
delete m_handler;
}
m_processor->AddLog(level, strMessage);
}
+void CCECBusDevice::SetCecVersion(cec_version newVersion)
+{
+ CStdString strLog;
+ m_cecVersion = newVersion;
+
+ switch (newVersion)
+ {
+ case CEC_VERSION_1_2:
+ strLog.Format("device %d reports CEC version 1.2", m_iLogicalAddress);
+ break;
+ case CEC_VERSION_1_2A:
+ strLog.Format("device %d reports CEC version 1.2a", m_iLogicalAddress);
+ break;
+ case CEC_VERSION_1_3:
+ strLog.Format("device %d reports CEC version 1.3", m_iLogicalAddress);
+ break;
+ case CEC_VERSION_1_3A:
+ strLog.Format("device %d reports CEC version 1.3a", m_iLogicalAddress);
+ break;
+ default:
+ strLog.Format("device %d reports an unknown CEC version", m_iLogicalAddress);
+ m_cecVersion = CEC_VERSION_UNKNOWN;
+ break;
+ }
+ AddLog(CEC_LOG_DEBUG, strLog);
+}
+
void CCECBusDevice::SetVendorId(const cec_datapacket &data)
{
if (data.size < 3)
CLockObject lock(&m_mutex);
m_iLastActive = GetTimeMs();
m_handler->HandleCommand(command);
+ m_condition.Signal();
return true;
}
return m_processor->Transmit(command);
}
+cec_version CCECBusDevice::GetCecVersion(void)
+{
+ if (m_cecVersion == CEC_VERSION_UNKNOWN)
+ {
+ AddLog(CEC_LOG_NOTICE, "<< requesting CEC version");
+ cec_command command;
+ cec_command::format(command, GetMyLogicalAddress(), m_iLogicalAddress, CEC_OPCODE_GET_CEC_VERSION);
+ CLockObject lock(&m_mutex);
+ if (m_processor->Transmit(command))
+ m_condition.Wait(&m_mutex, 1000);
+ }
+
+ return m_cecVersion;
+}
+
const char *CCECBusDevice::CECVendorIdToString(const uint64_t iVendorId)
{
switch (iVendorId)
virtual cec_logical_address GetMyLogicalAddress(void) const;
virtual uint16_t GetMyPhysicalAddress(void) const;
+ virtual void SetCecVersion(cec_version newVersion);
virtual void SetVendorId(const cec_datapacket &data);
virtual void SetVendorId(uint64_t iVendorId, uint8_t iVendorClass = 0);
virtual const char *GetVendorName(void) const { return CECVendorIdToString(m_iVendorId); }
virtual CCECProcessor *GetProcessor() const { return m_processor; }
virtual CCECCommandHandler *GetHandler(void) const { return m_handler; };
+ virtual cec_version GetCecVersion(void);
virtual void PollVendorId(void);
virtual bool PowerOn(void);
virtual bool Standby(void);
uint64_t m_iVendorId;
uint8_t m_iVendorClass;
uint64_t m_iLastActive;
+ cec_version m_cecVersion;
CMutex m_mutex;
+ CCondition m_condition;
};
};
{
switch(command.opcode)
{
+ case CEC_OPCODE_CEC_VERSION:
+ HandleDeviceCecVersion(command);
+ break;
case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
HandleGivePhysicalAddress(command);
break;
return bHandled;
}
+bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command)
+{
+ if (command.parameters.size == 1)
+ {
+ CCECBusDevice *device = GetDevice(command.initiator);
+ if (device)
+ device->SetCecVersion((cec_version) command.parameters[0]);
+ }
+
+ return true;
+}
+
bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
{
CCECBusDevice *device = GetDevice(command.initiator);
if (device)
device->SetVendorId(command.parameters);
- return false;
+ return true;
}
bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command)
if (device)
device->SetVendorId(command.parameters);
- return false;
+ return true;
}
bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command)
virtual cec_vendor_id GetVendorId(void) { return CEC_VENDOR_UNKNOWN; };
protected:
+ bool HandleDeviceCecVersion(const cec_command &command);
bool HandleDeviceVendorCommandWithId(const cec_command &command);
bool HandleDeviceVendorId(const cec_command &command);
bool HandleGetCecVersion(const cec_command &command);
"osd {addr} {string} set OSD message on the specified device." << endl <<
"[osd 0 Test Message] displays 'Test Message' on the TV" << endl <<
endl <<
+ "ver {addr} get the CEC version of the specified device." << endl <<
+ "[ver 0] get the CEC version 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 <<
{
parser->StartBootloader();
}
+ else if (command == "ver")
+ {
+ CStdString strDev;
+ if (GetWord(input, strDev))
+ {
+ int iDev = atoi(strDev);
+ if (iDev >= 0 && iDev < 15)
+ {
+ cec_version iVersion = parser->GetDeviceCecVersion((cec_logical_address) iDev);
+ switch (iVersion)
+ {
+ case CEC_VERSION_1_2:
+ cout << "CEC version 1.2" << endl;
+ break;
+ case CEC_VERSION_1_2A:
+ cout << "CEC version 1.2a" << endl;
+ break;
+ case CEC_VERSION_1_3:
+ cout << "CEC version 1.3" << endl;
+ break;
+ case CEC_VERSION_1_3A:
+ cout << "CEC version 1.3a" << endl;
+ break;
+ default:
+ cout << "unknown CEC version" << endl;
+ break;
+ }
+ }
+ }
+ }
else if (command == "r")
{
cout << "closing the connection" << endl;