From 5f150ee2e57b5c3e16361074e37b5bdb54b687ab Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sat, 8 Oct 2011 17:36:04 +0200 Subject: [PATCH] cec: parse and store the vendor id and device class of devices. only the vendor ID of Samsung (240) is currently detected. --- include/CECExports.h | 32 ++++++++++++++++++++++++++++---- src/lib/CECProcessor.cpp | 38 +++++++++++++++++++++++++++++++++----- src/lib/CECProcessor.h | 3 +++ 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/include/CECExports.h b/include/CECExports.h index 47dcdff..16f24df 100644 --- a/include/CECExports.h +++ b/include/CECExports.h @@ -263,11 +263,18 @@ namespace CEC { uint8_t data[20]; uint8_t size; - void shift(uint8_t num) + void shift(uint8_t iShiftBy) { - for (uint8_t iPtr = 0; iPtr < num; iPtr++) - data[iPtr] = iPtr + num < size ? data[iPtr + num] : 0; - size -= num; + if (iShiftBy >= size) + { + clear(); + } + else + { + for (uint8_t iPtr = 0; iPtr < size; iPtr++) + data[iPtr] = (iPtr + iShiftBy < size) ? data[iPtr + iShiftBy] : 0; + size = (uint8_t) (size - iShiftBy); + } } void push_back(uint8_t add) @@ -299,6 +306,23 @@ namespace CEC { }; } cec_command; + typedef enum cec_vendor_id + { + CEC_VENDOR_SAMSUNG = 240, + CEC_VENDOR_UNKNOWN = 0 + } vendor_id; + + static const char *CECVendorIdToString(const uint64_t iVendorId) + { + switch (iVendorId) + { + case CEC_VENDOR_SAMSUNG: + return "Samsung"; + default: + return "Unknown"; + } + } + //default physical address 1.0.0.0 #define CEC_DEFAULT_PHYSICAL_ADDRESS 0x1000 diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 85eb1de..7edea00 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -47,6 +47,10 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm m_communication(serComm), m_controller(controller) { + for (uint8_t iPtr = 0; iPtr < 16; iPtr++) + m_vendorIds[iPtr] = CEC_VENDOR_UNKNOWN; + for (uint8_t iPtr = 0; iPtr < 16; iPtr++) + m_vendorClasses[iPtr] = (uint8_t) 0; } CCECProcessor::~CCECProcessor(void) @@ -509,6 +513,26 @@ bool CCECProcessor::ParseMessage(cec_frame &msg) return bReturn; } +void CCECProcessor::ParseVendorId(cec_logical_address device, cec_frame data) +{ + if (data.size < 3) + { + m_controller->AddLog(CEC_LOG_WARNING, "invalid vendor ID received"); + return; + } + + uint64_t iVendorId = ((uint64_t)data.data[0] << 3) + + ((uint64_t)data.data[1] << 2) + + (uint64_t)data.data[2]; + + m_vendorIds[(uint8_t)device] = iVendorId; + m_vendorClasses[(uint8_t)device] = data.size >= 4 ? data.data[3] : 0; + + CStdString strLog; + strLog.Format("device %d: vendor = %s (%lld) class = %2x", (uint8_t)device, CECVendorIdToString(m_vendorIds[(uint8_t)device]), iVendorId, m_vendorClasses[(uint8_t)device]); + m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); +} + void CCECProcessor::ParseCurrentFrame(cec_frame &frame) { uint8_t initiator = frame.data[0] >> 4; @@ -535,7 +559,6 @@ void CCECProcessor::ParseCurrentFrame(cec_frame &frame) { case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: ReportPhysicalAddress(); - SetActiveView(); break; case CEC_OPCODE_GIVE_OSD_NAME: ReportOSDName((cec_logical_address)initiator); @@ -543,11 +566,17 @@ void CCECProcessor::ParseCurrentFrame(cec_frame &frame) case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID: ReportVendorID((cec_logical_address)initiator); break; + case CEC_OPCODE_VENDOR_COMMAND_WITH_ID: + frame.shift(2); + ParseVendorId((cec_logical_address)initiator, frame); + TransmitAbort((cec_logical_address)initiator, CEC_OPCODE_VENDOR_COMMAND_WITH_ID); + break; case CEC_OPCODE_MENU_REQUEST: ReportMenuState((cec_logical_address)initiator); break; case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS: ReportPowerState((cec_logical_address)initiator); + SetActiveView(); break; case CEC_OPCODE_GET_CEC_VERSION: ReportCECVersion((cec_logical_address)initiator); @@ -565,9 +594,8 @@ void CCECProcessor::ParseCurrentFrame(cec_frame &frame) m_controller->AddKey(); break; default: - cec_frame params = frame; - params.shift(2); - m_controller->AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); + frame.shift(2); + m_controller->AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, &frame); break; } } @@ -594,7 +622,7 @@ void CCECProcessor::ParseCurrentFrame(cec_frame &frame) else { cec_frame params = frame; - params.shift(2); + frame.shift(2); m_controller->AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); } } diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index ef2be9c..2084d1a 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -75,6 +75,7 @@ namespace CEC bool WaitForAck(bool *bError, uint32_t iTimeout = 1000); bool ParseMessage(cec_frame &msg); void ParseCurrentFrame(cec_frame &frame); + void ParseVendorId(cec_logical_address device, cec_frame data); cec_frame m_currentframe; uint16_t m_physicaladdress; @@ -84,5 +85,7 @@ namespace CEC CMutex m_mutex; CAdapterCommunication *m_communication; CLibCEC *m_controller; + uint64_t m_vendorIds[16]; + uint8_t m_vendorClasses[16]; }; }; -- 2.34.1