X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;h=0c409eb6eee23073393373c1ce27d424946d4647;hb=b5e7f745432c989c382b7729d64ea4a45c9dd49b;hp=c23cb93315094127c37edb0beaa692bf522203f4;hpb=578c3905a5d00d54611bbcd0da3f6cf8ad9263ac;p=deb_libcec.git diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index c23cb93..0c409eb 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -32,7 +32,7 @@ #include "CECProcessor.h" -#include "AdapterCommunication.h" +#include "adapter/AdapterMessage.h" #include "devices/CECBusDevice.h" #include "devices/CECAudioSystem.h" #include "devices/CECPlaybackDevice.h" @@ -149,24 +149,44 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint if ((bReturn = m_communication->Open(strPort, iBaudRate, iTimeoutMs)) == false) m_controller->AddLog(CEC_LOG_ERROR, "could not open a connection"); + /* try to ping the adapter */ + if ((bReturn = m_communication->PingAdapter()) == false) + m_controller->AddLog(CEC_LOG_ERROR, "the adapter does not respond correctly"); + + uint16_t iFirmwareVersion = m_communication->GetFirmwareVersion(); + if ((bReturn = (iFirmwareVersion != CEC_FW_VERSION_UNKNOWN)) == false) + m_controller->AddLog(CEC_LOG_ERROR, "the adapter is running an unknown firmware version"); + + CStdString strLog; + strLog.Format("CEC Adapter firmware version: %d", iFirmwareVersion); + m_controller->AddLog(CEC_LOG_NOTICE, strLog); + return bReturn; } -bool CCECProcessor::Initialise(void) +void CCECProcessor::SetInitialised(bool bSetTo /* = true */) { - bool bReturn(false); CLockObject lock(m_mutex); - if (!m_logicalAddresses.IsEmpty()) - m_logicalAddresses.Clear(); + m_bInitialised = bSetTo; +} - if (!FindLogicalAddresses()) +bool CCECProcessor::Initialise(void) +{ + bool bReturn(false); { - m_controller->AddLog(CEC_LOG_ERROR, "could not detect our logical addresses"); - return bReturn; - } + CLockObject lock(m_mutex); + if (!m_logicalAddresses.IsEmpty()) + m_logicalAddresses.Clear(); + + if (!FindLogicalAddresses()) + { + m_controller->AddLog(CEC_LOG_ERROR, "could not detect our logical addresses"); + return bReturn; + } - /* only set our OSD name for the primary device */ - m_busDevices[m_logicalAddresses.primary]->m_strDeviceName = m_strDeviceName; + /* only set our OSD name for the primary device */ + m_busDevices[m_logicalAddresses.primary]->m_strDeviceName = m_strDeviceName; + } /* get the vendor id from the TV, so we are using the correct handler */ m_busDevices[CECDEVICE_TV]->RequestVendorId(); @@ -175,11 +195,11 @@ bool CCECProcessor::Initialise(void) if ((bReturn = SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true)) == false) { CStdString strLog; - strLog.Format("unable to set the correct HDMI port (HDMI %d on %s(%x)", m_iHDMIPort, ToString(m_iBaseDevice), (uint8_t)m_iBaseDevice); + strLog.Format("unable to set HDMI port %d on %s (%x)", m_iHDMIPort, ToString(m_iBaseDevice), (uint8_t)m_iBaseDevice); m_controller->AddLog(CEC_LOG_ERROR, strLog); } - else - m_bInitialised = true; + + SetInitialised(bReturn); return bReturn; } @@ -388,7 +408,7 @@ void *CCECProcessor::Process(void) { ReplaceHandlers(); command.Clear(); - msg.clear(); + msg.Clear(); { CLockObject lock(m_mutex); @@ -840,9 +860,9 @@ bool CCECProcessor::Transmit(const cec_command &data) bReturn = Transmit(output); /* set to "not present" on failed ack */ - if (output->is_error() && output->reply == MSGCODE_TRANSMIT_FAILED_ACK && - output->destination() != CECDEVICE_BROADCAST) - m_busDevices[output->destination()]->SetDeviceStatus(CEC_DEVICE_STATUS_NOT_PRESENT); + if (output->state == ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED && + output->Destination() != CECDEVICE_BROADCAST) + m_busDevices[output->Destination()]->SetDeviceStatus(CEC_DEVICE_STATUS_NOT_PRESENT); delete output; return bReturn; @@ -853,36 +873,19 @@ bool CCECProcessor::Transmit(CCECAdapterMessage *output) bool bReturn(false); CLockObject lock(m_mutex); { + if (!m_communication) + return bReturn; + m_iLastTransmission = GetTimeMs(); m_communication->SetLineTimeout(m_iStandardLineTimeout); - output->tries = 1; + output->tries = 0; do { if (output->tries > 0) m_communication->SetLineTimeout(m_iRetryLineTimeout); - - CLockObject msgLock(output->mutex); - if (!m_communication || !m_communication->Write(output)) - return bReturn; - else - { - output->condition.Wait(output->mutex); - if (output->state != ADAPTER_MESSAGE_STATE_SENT) - { - m_controller->AddLog(CEC_LOG_ERROR, "command was not sent"); - return bReturn; - } - } - - if (output->transmit_timeout > 0) - { - if ((bReturn = WaitForTransmitSucceeded(output)) == false) - m_controller->AddLog(CEC_LOG_DEBUG, "did not receive ack"); - } - else - bReturn = true; - }while (output->transmit_timeout > 0 && output->needs_retry() && ++output->tries < output->maxTries); + bReturn = m_communication->Write(output); + }while (!bReturn && output->transmit_timeout > 0 && output->NeedsRetry() && ++output->tries < output->maxTries); } m_communication->SetLineTimeout(m_iStandardLineTimeout); @@ -903,93 +906,25 @@ void CCECProcessor::TransmitAbort(cec_logical_address address, cec_opcode opcode Transmit(command); } -bool CCECProcessor::WaitForTransmitSucceeded(CCECAdapterMessage *message) -{ - bool bError(false); - bool bTransmitSucceeded(false); - uint8_t iPacketsLeft(message->size() / 4); - - int64_t iNow = GetTimeMs(); - int64_t iTargetTime = iNow + message->transmit_timeout; - - while (!bTransmitSucceeded && !bError && (message->transmit_timeout == 0 || iNow < iTargetTime)) - { - CCECAdapterMessage msg; - - if (!m_communication->Read(msg, message->transmit_timeout > 0 ? (int32_t)(iTargetTime - iNow) : 1000)) - { - iNow = GetTimeMs(); - continue; - } - - if (msg.message() == MSGCODE_FRAME_START && msg.ack()) - { - m_busDevices[msg.initiator()]->GetHandler()->HandlePoll(msg.initiator(), msg.destination()); - m_lastInitiator = msg.initiator(); - iNow = GetTimeMs(); - continue; - } - - bError = msg.is_error(); - if (msg.message() == MSGCODE_RECEIVE_FAILED && - m_lastInitiator != CECDEVICE_UNKNOWN && - !m_busDevices[m_lastInitiator]->GetHandler()->HandleReceiveFailed()) - { - iNow = GetTimeMs(); - continue; - } - - if (bError) - { - message->reply = msg.message(); - m_controller->AddLog(CEC_LOG_DEBUG, msg.ToString()); - } - else - { - switch(msg.message()) - { - case MSGCODE_COMMAND_ACCEPTED: - m_controller->AddLog(CEC_LOG_DEBUG, msg.ToString()); - if (iPacketsLeft > 0) - iPacketsLeft--; - break; - case MSGCODE_TRANSMIT_SUCCEEDED: - m_controller->AddLog(CEC_LOG_DEBUG, msg.ToString()); - bTransmitSucceeded = (iPacketsLeft == 0); - bError = !bTransmitSucceeded; - message->reply = MSGCODE_TRANSMIT_SUCCEEDED; - break; - default: - // ignore other data while waiting - break; - } - - iNow = GetTimeMs(); - } - } - - return bTransmitSucceeded && !bError; -} - bool CCECProcessor::ParseMessage(const CCECAdapterMessage &msg) { bool bEom(false); - bool bIsError(msg.is_error()); + bool bIsError(msg.IsError()); - if (msg.empty()) + if (msg.IsEmpty()) return bEom; - switch(msg.message()) + switch(msg.Message()) { case MSGCODE_FRAME_START: { m_currentframe.Clear(); - if (msg.size() >= 2) + if (msg.Size() >= 2) { - m_currentframe.initiator = msg.initiator(); - m_currentframe.destination = msg.destination(); - m_currentframe.ack = msg.ack(); - m_currentframe.eom = msg.eom(); + m_currentframe.initiator = msg.Initiator(); + m_currentframe.destination = msg.Destination(); + m_currentframe.ack = msg.IsACK(); + m_currentframe.eom = msg.IsEOM(); } if (m_currentframe.ack == 0x1) { @@ -1006,12 +941,12 @@ bool CCECProcessor::ParseMessage(const CCECAdapterMessage &msg) break; case MSGCODE_FRAME_DATA: { - if (msg.size() >= 2) + if (msg.Size() >= 2) { m_currentframe.PushBack(msg[1]); - m_currentframe.eom = msg.eom(); + m_currentframe.eom = msg.IsEOM(); } - bEom = msg.eom(); + bEom = msg.IsEOM(); } break; default: @@ -1096,25 +1031,7 @@ void CCECProcessor::AddLog(cec_log_level level, const CStdString &strMessage) bool CCECProcessor::SetAckMask(uint16_t iMask) { - bool bReturn(false); - CStdString strLog; - strLog.Format("setting ackmask to %2x", iMask); - m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str()); - - CCECAdapterMessage *output = new CCECAdapterMessage; - - output->push_back(MSGSTART); - output->push_escaped(MSGCODE_SET_ACK_MASK); - output->push_escaped(iMask >> 8); - output->push_escaped((uint8_t)iMask); - output->push_back(MSGEND); - - if ((bReturn = Transmit(output)) == false) - m_controller->AddLog(CEC_LOG_ERROR, "could not set the ackmask"); - - delete output; - - return bReturn; + return m_communication->SetAckMask(iMask); } bool CCECProcessor::TransmitKeypress(cec_logical_address iDestination, cec_user_control_code key, bool bWait /* = true */) @@ -1525,3 +1442,15 @@ bool CCECProcessor::PingAdapter(void) { return m_communication->PingAdapter(); } + +void CCECProcessor::HandlePoll(cec_logical_address initiator, cec_logical_address destination) +{ + m_busDevices[initiator]->GetHandler()->HandlePoll(initiator, destination); + m_lastInitiator = initiator; +} + +bool CCECProcessor::HandleReceiveFailed(void) +{ + return m_lastInitiator != CECDEVICE_UNKNOWN && + !m_busDevices[m_lastInitiator]->GetHandler()->HandleReceiveFailed(); +}