X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;fp=src%2Flib%2FCECParser.cpp;h=f3b89c3e3fe7e2e1382767430e063ad5e3451c06;hb=2abe74ebbd27d8c30060b3eebb363e10d3fbfd80;hp=a86da1a58f3411c7e23193ddb852cd971209e48e;hpb=828682d35c298ff062422521689258c363ea3579;p=deb_libcec.git diff --git a/src/lib/CECParser.cpp b/src/lib/CECProcessor.cpp similarity index 54% rename from src/lib/CECParser.cpp rename to src/lib/CECProcessor.cpp index a86da1a..f3b89c3 100644 --- a/src/lib/CECParser.cpp +++ b/src/lib/CECProcessor.cpp @@ -30,87 +30,55 @@ * http://www.pulse-eight.net/ */ -#include "CECParser.h" +#include "CECProcessor.h" -#include -#include -#include -#include -#include +#include "AdapterCommunication.h" +#include "LibCEC.h" #include "util/StdString.h" -#include "libPlatform/serialport.h" -#include "util/threads.h" #include "util/timeutils.h" -#include "CECDetect.h" -#include "AdapterCommunication.h" using namespace CEC; using namespace std; -#define CEC_MAX_RETRY 5 -#define CEC_BUTTON_TIMEOUT 500 - -/*! - * ICECDevice implementation - */ -//@{ -CCECParser::CCECParser(const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, int iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) : - m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN), +CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, int iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) : m_physicaladdress(iPhysicalAddress), m_iLogicalAddress(iLogicalAddress), - m_strDeviceName(strDeviceName) + m_strDeviceName(strDeviceName), + m_communication(serComm), + m_controller(controller) { - m_communication = new CAdapterCommunication(this); } -CCECParser::~CCECParser(void) +CCECProcessor::~CCECProcessor(void) { - Close(); - m_communication->Close(); - delete m_communication; + StopThread(); + m_communication = NULL; + m_controller = NULL; } -bool CCECParser::Open(const char *strPort, int iTimeoutMs /* = 10000 */) +bool CCECProcessor::Start(void) { - if (!m_communication) - return false; - - if (m_communication->IsOpen()) - { - AddLog(CEC_LOG_ERROR, "connection already open"); + if (!m_communication || !m_communication->IsOpen()) return false; - } - - if (!m_communication->Open(strPort, 38400, iTimeoutMs)) - { - AddLog(CEC_LOG_ERROR, "could not open a connection"); - return false; - } if (!SetLogicalAddress(m_iLogicalAddress)) { - AddLog(CEC_LOG_ERROR, "could not set the logical address"); + m_controller->AddLog(CEC_LOG_ERROR, "could not set the logical address"); return false; } if (CreateThread()) return true; else - AddLog(CEC_LOG_ERROR, "could not create a processor thread"); + m_controller->AddLog(CEC_LOG_ERROR, "could not create a processor thread"); return false; } -void CCECParser::Close(void) +void *CCECProcessor::Process(void) { - StopThread(); -} - -void *CCECParser::Process(void) -{ - AddLog(CEC_LOG_DEBUG, "processor thread started"); + m_controller->AddLog(CEC_LOG_DEBUG, "processor thread started"); - int64_t now = GetTimeMs(); while (!m_bStop) { bool bParseFrame(false); @@ -124,103 +92,48 @@ void *CCECParser::Process(void) if (bParseFrame) ParseCurrentFrame(); - now = GetTimeMs(); - CheckKeypressTimeout(now); + m_controller->CheckKeypressTimeout(); CCondition::Sleep(50); } - AddLog(CEC_LOG_DEBUG, "processor thread terminated"); + m_controller->AddLog(CEC_LOG_DEBUG, "processor thread terminated"); return NULL; } -bool CCECParser::Ping(void) -{ - if (!IsRunning()) - return false; - - AddLog(CEC_LOG_DEBUG, "sending ping"); - cec_frame output; - output.push_back(MSGSTART); - PushEscaped(output, MSGCODE_PING); - output.push_back(MSGEND); - - if (!TransmitFormatted(output, false)) - { - AddLog(CEC_LOG_ERROR, "could not send ping command"); - return false; - } - - AddLog(CEC_LOG_DEBUG, "ping tranmitted"); - - // TODO check for pong - return true; -} - -bool CCECParser::StartBootloader(void) -{ - if (!IsRunning()) - return false; - - AddLog(CEC_LOG_DEBUG, "starting the bootloader"); - cec_frame output; - output.push_back(MSGSTART); - PushEscaped(output, MSGCODE_START_BOOTLOADER); - output.push_back(MSGEND); - - if (!TransmitFormatted(output, false)) - { - AddLog(CEC_LOG_ERROR, "could not start the bootloader"); - return false; - } - - AddLog(CEC_LOG_DEBUG, "bootloader start command transmitted"); - return true; -} - -uint8_t CCECParser::GetSourceDestination(cec_logical_address destination /* = CECDEVICE_BROADCAST */) -{ - return ((uint8_t)m_iLogicalAddress << 4) + (uint8_t)destination; -} - -bool CCECParser::PowerOffDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) -{ - return StandbyDevices(address); -} - -bool CCECParser::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */) +bool CCECProcessor::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */) { if (!IsRunning()) return false; CStdString strLog; strLog.Format("powering on devices with logical address %d", (int8_t)address); - AddLog(CEC_LOG_DEBUG, strLog.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); cec_frame frame; frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_TEXT_VIEW_ON); return Transmit(frame); } -bool CCECParser::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) +bool CCECProcessor::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) { if (!IsRunning()) return false; CStdString strLog; strLog.Format("putting all devices with logical address %d in standby mode", (int8_t)address); - AddLog(CEC_LOG_DEBUG, strLog.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); cec_frame frame; frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_STANDBY); return Transmit(frame); } -bool CCECParser::SetActiveView(void) +bool CCECProcessor::SetActiveView(void) { if (!IsRunning()) return false; - AddLog(CEC_LOG_DEBUG, "setting active view"); + m_controller->AddLog(CEC_LOG_DEBUG, "setting active view"); cec_frame frame; frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); frame.push_back(CEC_OPCODE_ACTIVE_SOURCE); @@ -229,12 +142,12 @@ bool CCECParser::SetActiveView(void) return Transmit(frame); } -bool CCECParser::SetInactiveView(void) +bool CCECProcessor::SetInactiveView(void) { if (!IsRunning()) return false; - AddLog(CEC_LOG_DEBUG, "setting inactive view"); + m_controller->AddLog(CEC_LOG_DEBUG, "setting inactive view"); cec_frame frame; frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); frame.push_back(CEC_OPCODE_INACTIVE_SOURCE); @@ -243,25 +156,78 @@ bool CCECParser::SetInactiveView(void) return Transmit(frame); } -bool CCECParser::GetNextLogMessage(cec_log_message *message) +bool CCECProcessor::Transmit(const cec_frame &data, bool bWaitForAck /* = true */) { - return m_logBuffer.Pop(*message); + CStdString txStr = "transmit "; + for (unsigned int i = 0; i < data.size(); i++) + txStr.AppendFormat(" %02x", data[i]); + m_controller->AddLog(CEC_LOG_DEBUG, txStr.c_str()); + + if (data.empty()) + { + m_controller->AddLog(CEC_LOG_WARNING, "transmit buffer is empty"); + return false; + } + + cec_frame output; + + //set ack polarity to high when transmitting to the broadcast address + //set ack polarity low when transmitting to any other address + output.push_back(MSGSTART); + CAdapterCommunication::PushEscaped(output, MSGCODE_TRANSMIT_ACK_POLARITY); + + if ((data[0] & 0xF) == 0xF) + CAdapterCommunication::PushEscaped(output, CEC_TRUE); + else + CAdapterCommunication::PushEscaped(output, CEC_FALSE); + + output.push_back(MSGEND); + + for (unsigned int i = 0; i < data.size(); i++) + { + output.push_back(MSGSTART); + + if (i == data.size() - 1) + CAdapterCommunication::PushEscaped(output, MSGCODE_TRANSMIT_EOM); + else + CAdapterCommunication::PushEscaped(output, MSGCODE_TRANSMIT); + + CAdapterCommunication::PushEscaped(output, data[i]); + + output.push_back(MSGEND); + } + + return TransmitFormatted(output, bWaitForAck); } -bool CCECParser::GetNextKeypress(cec_keypress *key) +bool CCECProcessor::SetLogicalAddress(cec_logical_address iLogicalAddress) { - return IsRunning() ? m_keyBuffer.Pop(*key) : false; + CStdString strLog; + strLog.Format("setting logical address to %d", iLogicalAddress); + m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str()); + + m_iLogicalAddress = iLogicalAddress; + return m_communication && m_communication->SetAckMask(0x1 << (uint8_t)m_iLogicalAddress); } -bool CCECParser::GetNextCommand(cec_command *command) +bool CCECProcessor::TransmitFormatted(const cec_frame &data, bool bWaitForAck /* = true */) { - return IsRunning() ? m_commandBuffer.Pop(*command) : false; + CLockObject lock(&m_mutex); + if (!m_communication || !m_communication->Write(data)) + return false; + + if (bWaitForAck && !WaitForAck()) + { + m_controller->AddLog(CEC_LOG_DEBUG, "did not receive ACK"); + return false; + } + + return true; } -//@} -void CCECParser::TransmitAbort(cec_logical_address address, cec_opcode opcode, ECecAbortReason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */) +void CCECProcessor::TransmitAbort(cec_logical_address address, cec_opcode opcode, ECecAbortReason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */) { - AddLog(CEC_LOG_DEBUG, "transmitting abort message"); + m_controller->AddLog(CEC_LOG_DEBUG, "transmitting abort message"); cec_frame frame; frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_FEATURE_ABORT); @@ -270,23 +236,23 @@ void CCECParser::TransmitAbort(cec_logical_address address, cec_opcode opcode, E Transmit(frame); } -void CCECParser::ReportCECVersion(cec_logical_address address /* = CECDEVICE_TV */) +void CCECProcessor::ReportCECVersion(cec_logical_address address /* = CECDEVICE_TV */) { cec_frame frame; - AddLog(CEC_LOG_NOTICE, "reporting CEC version as 1.3a"); + m_controller->AddLog(CEC_LOG_NOTICE, "reporting CEC version as 1.3a"); frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_CEC_VERSION); frame.push_back(CEC_VERSION_1_3A); Transmit(frame); } -void CCECParser::ReportPowerState(cec_logical_address address /*= CECDEVICE_TV */, bool bOn /* = true */) +void CCECProcessor::ReportPowerState(cec_logical_address address /*= CECDEVICE_TV */, bool bOn /* = true */) { cec_frame frame; if (bOn) - AddLog(CEC_LOG_NOTICE, "reporting \"On\" power status"); + m_controller->AddLog(CEC_LOG_NOTICE, "reporting \"On\" power status"); else - AddLog(CEC_LOG_NOTICE, "reporting \"Off\" power status"); + m_controller->AddLog(CEC_LOG_NOTICE, "reporting \"Off\" power status"); frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_REPORT_POWER_STATUS); @@ -294,13 +260,13 @@ void CCECParser::ReportPowerState(cec_logical_address address /*= CECDEVICE_TV * Transmit(frame); } -void CCECParser::ReportMenuState(cec_logical_address address /* = CECDEVICE_TV */, bool bActive /* = true */) +void CCECProcessor::ReportMenuState(cec_logical_address address /* = CECDEVICE_TV */, bool bActive /* = true */) { cec_frame frame; if (bActive) - AddLog(CEC_LOG_NOTICE, "reporting menu state as active"); + m_controller->AddLog(CEC_LOG_NOTICE, "reporting menu state as active"); else - AddLog(CEC_LOG_NOTICE, "reporting menu state as inactive"); + m_controller->AddLog(CEC_LOG_NOTICE, "reporting menu state as inactive"); frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_MENU_STATUS); @@ -308,19 +274,19 @@ void CCECParser::ReportMenuState(cec_logical_address address /* = CECDEVICE_TV * Transmit(frame); } -void CCECParser::ReportVendorID(cec_logical_address address /* = CECDEVICE_TV */) +void CCECProcessor::ReportVendorID(cec_logical_address address /* = CECDEVICE_TV */) { - AddLog(CEC_LOG_NOTICE, "vendor ID requested, feature abort"); + m_controller->AddLog(CEC_LOG_NOTICE, "vendor ID requested, feature abort"); TransmitAbort(address, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); } -void CCECParser::ReportOSDName(cec_logical_address address /* = CECDEVICE_TV */) +void CCECProcessor::ReportOSDName(cec_logical_address address /* = CECDEVICE_TV */) { cec_frame frame; const char *osdname = m_strDeviceName.c_str(); CStdString strLog; strLog.Format("reporting OSD name as %s", osdname); - AddLog(CEC_LOG_NOTICE, strLog.c_str()); + m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str()); frame.push_back(GetSourceDestination(address)); frame.push_back(CEC_OPCODE_SET_OSD_NAME); @@ -330,12 +296,12 @@ void CCECParser::ReportOSDName(cec_logical_address address /* = CECDEVICE_TV */) Transmit(frame); } -void CCECParser::ReportPhysicalAddress(void) +void CCECProcessor::ReportPhysicalAddress(void) { cec_frame frame; CStdString strLog; strLog.Format("reporting physical address as %04x", m_physicaladdress); - AddLog(CEC_LOG_NOTICE, strLog.c_str()); + m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str()); frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); frame.push_back(CEC_OPCODE_REPORT_PHYSICAL_ADDRESS); frame.push_back((m_physicaladdress >> 8) & 0xFF); @@ -344,10 +310,10 @@ void CCECParser::ReportPhysicalAddress(void) Transmit(frame); } -void CCECParser::BroadcastActiveSource(void) +void CCECProcessor::BroadcastActiveSource(void) { cec_frame frame; - AddLog(CEC_LOG_NOTICE, "broadcasting active source"); + m_controller->AddLog(CEC_LOG_NOTICE, "broadcasting active source"); frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); frame.push_back(CEC_OPCODE_ACTIVE_SOURCE); frame.push_back((m_physicaladdress >> 8) & 0xFF); @@ -355,69 +321,12 @@ void CCECParser::BroadcastActiveSource(void) Transmit(frame); } -bool CCECParser::TransmitFormatted(const cec_frame &data, bool bWaitForAck /* = true */) -{ - CLockObject lock(&m_mutex); - if (!m_communication || !m_communication->Write(data)) - { - return false; - } - - CCondition::Sleep((int) data.size() * 24 /*data*/ + 5 /*start bit (4.5 ms)*/ + 50 /* to be on the safe side */); - if (bWaitForAck && !WaitForAck()) - { - AddLog(CEC_LOG_DEBUG, "did not receive ACK"); - return false; - } - - return true; -} - -bool CCECParser::Transmit(const cec_frame &data, bool bWaitForAck /* = true */) +uint8_t CCECProcessor::GetSourceDestination(cec_logical_address destination /* = CECDEVICE_BROADCAST */) const { - CStdString txStr = "transmit "; - for (unsigned int i = 0; i < data.size(); i++) - txStr.AppendFormat(" %02x", data[i]); - AddLog(CEC_LOG_DEBUG, txStr.c_str()); - - if (data.empty()) - { - AddLog(CEC_LOG_WARNING, "transmit buffer is empty"); - return false; - } - - cec_frame output; - - //set ack polarity to high when transmitting to the broadcast address - //set ack polarity low when transmitting to any other address - output.push_back(MSGSTART); - PushEscaped(output, MSGCODE_TRANSMIT_ACK_POLARITY); - - if ((data[0] & 0xF) == 0xF) - PushEscaped(output, CEC_TRUE); - else - PushEscaped(output, CEC_FALSE); - - output.push_back(MSGEND); - - for (unsigned int i = 0; i < data.size(); i++) - { - output.push_back(MSGSTART); - - if (i == data.size() - 1) - PushEscaped(output, MSGCODE_TRANSMIT_EOM); - else - PushEscaped(output, MSGCODE_TRANSMIT); - - PushEscaped(output, data[i]); - - output.push_back(MSGEND); - } - - return TransmitFormatted(output, bWaitForAck); + return ((uint8_t)m_iLogicalAddress << 4) + (uint8_t)destination; } -bool CCECParser::WaitForAck(int iTimeout /* = 1000 */) +bool CCECProcessor::WaitForAck(int iTimeout /* = 1000 */) { bool bGotAck(false); bool bError(false); @@ -435,35 +344,35 @@ bool CCECParser::WaitForAck(int iTimeout /* = 1000 */) switch (iCode) { case MSGCODE_COMMAND_ACCEPTED: - AddLog(CEC_LOG_DEBUG, "MSGCODE_COMMAND_ACCEPTED"); + m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_COMMAND_ACCEPTED"); break; case MSGCODE_TRANSMIT_SUCCEEDED: - AddLog(CEC_LOG_DEBUG, "MSGCODE_TRANSMIT_SUCCEEDED"); + m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_TRANSMIT_SUCCEEDED"); // TODO bGotAck = true; break; case MSGCODE_RECEIVE_FAILED: - AddLog(CEC_LOG_WARNING, "MSGCODE_RECEIVE_FAILED"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_RECEIVE_FAILED"); bError = true; break; case MSGCODE_COMMAND_REJECTED: - AddLog(CEC_LOG_WARNING, "MSGCODE_COMMAND_REJECTED"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_COMMAND_REJECTED"); bError = true; break; case MSGCODE_TRANSMIT_FAILED_LINE: - AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_LINE"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_LINE"); bError = true; break; case MSGCODE_TRANSMIT_FAILED_ACK: - AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_ACK"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_ACK"); bError = true; break; case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: - AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA"); bError = true; break; case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: - AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE"); + m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE"); bError = true; break; default: @@ -478,7 +387,7 @@ bool CCECParser::WaitForAck(int iTimeout /* = 1000 */) return bGotAck && !bError; } -bool CCECParser::ParseMessage(cec_frame &msg) +bool CCECProcessor::ParseMessage(cec_frame &msg) { bool bReturn(false); @@ -493,7 +402,7 @@ bool CCECParser::ParseMessage(cec_frame &msg) switch(iCode) { case MSGCODE_NOTHING: - AddLog(CEC_LOG_DEBUG, "MSGCODE_NOTHING"); + m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_NOTHING"); break; case MSGCODE_TIMEOUT_ERROR: case MSGCODE_HIGH_ERROR: @@ -510,7 +419,7 @@ bool CCECParser::ParseMessage(cec_frame &msg) uint32_t iTime = (msg.size() >= 7) ? (msg[3] << 24) | (msg[4] << 16) | (msg[5] << 8) | (msg[6]) : 0; logStr.AppendFormat(" line:%i", iLine); logStr.AppendFormat(" time:%u", iTime); - AddLog(CEC_LOG_WARNING, logStr.c_str()); + m_controller->AddLog(CEC_LOG_WARNING, logStr.c_str()); } break; case MSGCODE_FRAME_START: @@ -525,7 +434,7 @@ bool CCECParser::ParseMessage(cec_frame &msg) m_currentframe.push_back(msg[1]); } - AddLog(CEC_LOG_DEBUG, logStr.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, logStr.c_str()); } break; case MSGCODE_FRAME_DATA: @@ -537,7 +446,7 @@ bool CCECParser::ParseMessage(cec_frame &msg) logStr.AppendFormat(" %02x", iData); m_currentframe.push_back(iData); } - AddLog(CEC_LOG_DEBUG, logStr.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, logStr.c_str()); } if (bEom) bReturn = true; @@ -549,7 +458,7 @@ bool CCECParser::ParseMessage(cec_frame &msg) return bReturn; } -void CCECParser::ParseCurrentFrame(void) +void CCECProcessor::ParseCurrentFrame(void) { uint8_t initiator = m_currentframe[0] >> 4; uint8_t destination = m_currentframe[0] & 0xF; @@ -563,7 +472,7 @@ void CCECParser::ParseCurrentFrame(void) for (unsigned int i = 1; i < m_currentframe.size(); i++) dataStr.AppendFormat(" %02x", m_currentframe[i]); } - AddLog(CEC_LOG_DEBUG, dataStr.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, dataStr.c_str()); if (m_currentframe.size() <= 1) return; @@ -596,22 +505,19 @@ void CCECParser::ParseCurrentFrame(void) case CEC_OPCODE_USER_CONTROL_PRESSED: if (m_currentframe.size() > 2) { - AddKey(); + m_controller->AddKey(); if (m_currentframe[2] <= CEC_USER_CONTROL_CODE_MAX) - { - m_iCurrentButton = (cec_user_control_code) m_currentframe[2]; - m_buttontime = GetTimeMs(); - } + m_controller->SetCurrentButton((cec_user_control_code) m_currentframe[2]); } break; case CEC_OPCODE_USER_CONTROL_RELEASE: - AddKey(); + m_controller->AddKey(); break; default: cec_frame params = m_currentframe; params.erase(params.begin(), params.begin() + 2); - AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); + m_controller->AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); break; } } @@ -628,7 +534,7 @@ void CCECParser::ParseCurrentFrame(void) int streamaddr = ((int)m_currentframe[2] << 8) | ((int)m_currentframe[3]); CStdString strLog; strLog.Format("%i requests stream path from physical address %04x", initiator, streamaddr); - AddLog(CEC_LOG_DEBUG, strLog.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); if (streamaddr == m_physicaladdress) BroadcastActiveSource(); } @@ -637,136 +543,13 @@ void CCECParser::ParseCurrentFrame(void) { cec_frame params = m_currentframe; params.erase(params.begin(), params.begin() + 2); - AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); + m_controller->AddCommand((cec_logical_address) initiator, (cec_logical_address) destination, opCode, ¶ms); } } else { CStdString strLog; strLog.Format("ignoring frame: destination: %u != %u", destination, (uint16_t)m_iLogicalAddress); - AddLog(CEC_LOG_DEBUG, strLog.c_str()); + m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); } } - -void CCECParser::PushEscaped(cec_frame &vec, uint8_t byte) -{ - if (byte >= MSGESC && byte != MSGSTART) - { - vec.push_back(MSGESC); - vec.push_back(byte - ESCOFFSET); - } - else - { - vec.push_back(byte); - } -} - -void CCECParser::CheckKeypressTimeout(int64_t now) -{ - if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && now - m_buttontime > CEC_BUTTON_TIMEOUT) - { - AddKey(); - m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; - } -} - -bool CCECParser::SetLogicalAddress(cec_logical_address iLogicalAddress) -{ - CStdString strLog; - strLog.Format("setting logical address to %d", iLogicalAddress); - AddLog(CEC_LOG_NOTICE, strLog.c_str()); - - m_iLogicalAddress = iLogicalAddress; - return SetAckMask(0x1 << (uint8_t)m_iLogicalAddress); -} - -bool CCECParser::SetAckMask(uint16_t iMask) -{ - CStdString strLog; - strLog.Format("setting ackmask to %2x", iMask); - AddLog(CEC_LOG_DEBUG, strLog.c_str()); - - cec_frame output; - - output.push_back(MSGSTART); - PushEscaped(output, MSGCODE_SET_ACK_MASK); - PushEscaped(output, iMask >> 8); - PushEscaped(output, (uint8_t)iMask); - output.push_back(MSGEND); - - if (!m_communication->Write(output)) - { - AddLog(CEC_LOG_ERROR, "could not set the ackmask"); - return false; - } - - return true; -} - -void CCECParser::AddLog(cec_log_level level, const string &strMessage) -{ - cec_log_message message; - message.level = level; - message.message.assign(strMessage.c_str()); - m_logBuffer.Push(message); -} - -void CCECParser::AddKey(void) -{ - if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN) - { - cec_keypress key; - key.duration = (unsigned int) (GetTimeMs() - m_buttontime); - key.keycode = m_iCurrentButton; - m_keyBuffer.Push(key); - m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; - m_buttontime = 0; - } -} - -void CCECParser::AddCommand(cec_logical_address source, cec_logical_address destination, cec_opcode opcode, cec_frame *parameters) -{ - cec_command command; - command.source = source; - command.destination = destination; - command.opcode = opcode; - if (parameters) - command.parameters = *parameters; - if (m_commandBuffer.Push(command)) - { - CStdString strDebug; - strDebug.Format("stored command '%d' in the command buffer. buffer size = %d", opcode, m_commandBuffer.Size()); - AddLog(CEC_LOG_DEBUG, strDebug); - } - else - { - AddLog(CEC_LOG_WARNING, "command buffer is full"); - } -} - -int CCECParser::GetMinVersion(void) -{ - return CEC_MIN_VERSION; -} - -int CCECParser::GetLibVersion(void) -{ - return CEC_LIB_VERSION; -} - -int CCECParser::FindDevices(std::vector &deviceList, const char *strDevicePath /* = NULL */) -{ - CStdString strDebug; - if (strDevicePath) - strDebug.Format("trying to autodetect the com port for device path '%s'", strDevicePath); - else - strDebug.Format("trying to autodetect all CEC adapters"); - AddLog(CEC_LOG_DEBUG, strDebug); - - return CCECDetect::FindDevices(deviceList, strDevicePath); -} - -DECLSPEC void * CECCreate(const char *strDeviceName, CEC::cec_logical_address iLogicalAddress /*= CEC::CECDEVICE_PLAYBACKDEVICE1 */, int iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */) -{ - return static_cast< void* > (new CCECParser(strDeviceName, iLogicalAddress, iPhysicalAddress)); -}