X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fadapter%2FUSBCECAdapterCommunication.cpp;h=1d3df13c907541d4863a902644f395bec06cfae1;hb=7cc92235bb5794e28b7bdb6f057b9e6a4c160f2d;hp=d98c20576adfbdd02acc14ba6b45eaf1f04ba645;hpb=e4a53f8e9db31df884891ef1f4c5607dd7458ad0;p=deb_libcec.git diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index d98c205..1d3df13 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -44,7 +44,7 @@ using namespace PLATFORM; #define CEC_ADAPTER_PING_TIMEOUT 15000 -CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = 38400 */) : +CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = CEC_SERIAL_DEFAULT_BAUDRATE */) : IAdapterCommunication(callback), m_port(NULL), m_iLineTimeout(0), @@ -67,7 +67,7 @@ CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void) delete m_port; } -bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */, bool bSkipChecks /* = false */, bool bStartListening /* = true */) +bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */, bool bSkipChecks /* = false */, bool bStartListening /* = true */) { bool bConnectionOpened(false); { @@ -92,7 +92,10 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */, bool b m_commands = new CUSBCECAdapterCommands(this); if (!m_adapterMessageQueue) + { m_adapterMessageQueue = new CCECAdapterMessageQueue(this); + m_adapterMessageQueue->CreateThread(); + } /* try to open the connection */ CStdString strError; @@ -146,58 +149,57 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */, bool b if (!bConnectionOpened || !bStartListening) StopThread(0); - if (!bConnectionOpened) - { - delete m_port; - m_port = NULL; - } return bConnectionOpened; } void CUSBCECAdapterCommunication::Close(void) { + /* stop the reader thread */ + StopThread(0); + + CLockObject lock(m_mutex); + /* set the ackmask to 0 before closing the connection */ - if (IsRunning()) + if (IsRunning() && m_port->IsOpen() && m_port->GetErrorNumber() == 0) { + CLibCEC::AddLog(CEC_LOG_DEBUG, "%s - closing the connection", __FUNCTION__); SetAckMask(0); if (m_commands->GetFirmwareVersion() >= 2) SetControlledMode(false); } + m_adapterMessageQueue->Clear(); + /* stop and delete the ping thread */ if (m_pingThread) m_pingThread->StopThread(0); delete m_pingThread; m_pingThread = NULL; - /* stop the reader thread */ - StopThread(0); - /* close and delete the com port connection */ if (m_port) m_port->Close(); + + libcec_parameter param; + CLibCEC::Alert(CEC_ALERT_CONNECTION_LOST, param); } -cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, uint8_t iMaxTries, uint8_t iLineTimeout /* = 3 */, uint8_t iRetryLineTimeout /* = 3 */) +cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout) { cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN); if (!IsRunning()) return retVal; - CCECAdapterMessage *output = new CCECAdapterMessage(data, iMaxTries, iLineTimeout, iRetryLineTimeout); + CCECAdapterMessage *output = new CCECAdapterMessage(data, iLineTimeout); /* mark as waiting for an ack from the destination */ MarkAsWaiting(data.destination); /* send the message */ - bool bRetry(true); - while (bRetry && ++output->tries < output->maxTries) - { - bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0; - if (bRetry) - Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); - } + bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0; + if (bRetry) + Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); retVal = output->state; delete output; @@ -264,7 +266,7 @@ void CUSBCECAdapterCommunication::MarkAsWaiting(const cec_logical_address dest) } } -void CUSBCECAdapterCommunication::ClearInputBytes(uint32_t iTimeout /* = 1000 */) +void CUSBCECAdapterCommunication::ClearInputBytes(uint32_t iTimeout /* = CEC_CLEAR_INPUT_DEFAULT_WAIT */) { CTimeout timeout(iTimeout); uint8_t buff[1024]; @@ -303,7 +305,7 @@ bool CUSBCECAdapterCommunication::WriteToDevice(CCECAdapterMessage *message) CLockObject adapterLock(m_mutex); if (!m_port->IsOpen()) { - CLibCEC::AddLog(CEC_LOG_DEBUG, "error writing command '%s' to the serial port: the connection is closed", CCECAdapterMessage::ToString(message->Message())); + CLibCEC::AddLog(CEC_LOG_DEBUG, "error writing command '%s' to serial port '%s': the connection is closed", CCECAdapterMessage::ToString(message->Message()), m_port->GetName().c_str()); message->state = ADAPTER_MESSAGE_STATE_ERROR; return false; } @@ -311,8 +313,9 @@ bool CUSBCECAdapterCommunication::WriteToDevice(CCECAdapterMessage *message) /* write the message */ if (m_port->Write(message->packet.data, message->Size()) != (ssize_t) message->Size()) { - CLibCEC::AddLog(CEC_LOG_DEBUG, "error writing command '%s' to the serial port: %s", CCECAdapterMessage::ToString(message->Message()), m_port->GetError().c_str()); + CLibCEC::AddLog(CEC_LOG_DEBUG, "error writing command '%s' to serial port '%s': %s", CCECAdapterMessage::ToString(message->Message()), m_port->GetName().c_str(), m_port->GetError().c_str()); message->state = ADAPTER_MESSAGE_STATE_ERROR; + Close(); return false; } @@ -331,17 +334,21 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize /* read from the serial port */ { CLockObject lock(m_mutex); - if (!m_port) + if (!m_port || !m_port->IsOpen()) return false; + iBytesRead = m_port->Read(buff, sizeof(uint8_t) * iSize, iTimeout); + + if (m_port->GetErrorNumber()) + { + CLibCEC::AddLog(CEC_LOG_ERROR, "error reading from serial port: %s", m_port->GetError().c_str()); + m_port->Close(); + return false; + } } if (iBytesRead < 0 || iBytesRead > 256) - { - CLibCEC::AddLog(CEC_LOG_ERROR, "error reading from serial port: %s", m_port->GetError().c_str()); - StopThread(false); return false; - } else if (iBytesRead > 0) { /* add the data to the current frame */ @@ -367,12 +374,14 @@ CCECAdapterMessage *CUSBCECAdapterCommunication::SendCommand(cec_adapter_message /* write the command */ if (!m_adapterMessageQueue->Write(output)) { - // timed out + if (output->state == ADAPTER_MESSAGE_STATE_ERROR) + Close(); return output; } else { - if (!bIsRetry && output->Reply() == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED) + if (!bIsRetry && output->Reply() == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED && + msgCode != MSGCODE_GET_BUILDDATE /* same messagecode value had a different meaning in older fw builds */) { /* if the controller reported that the command was rejected, and we didn't send the command to set controlled mode, then the controller probably switched to auto mode. set controlled @@ -387,7 +396,7 @@ CCECAdapterMessage *CUSBCECAdapterCommunication::SendCommand(cec_adapter_message return output; } -bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = 10000 */) +bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */) { bool bReturn(false); CTimeout timeout(iTimeoutMs > 0 ? iTimeoutMs : CEC_DEFAULT_TRANSMIT_WAIT); @@ -417,6 +426,9 @@ bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = 10000 */ else bReturn = true; + /* try to read the build date */ + m_commands->RequestBuildDate(); + SetInitialised(bReturn); return bReturn; } @@ -446,20 +458,17 @@ bool CUSBCECAdapterCommunication::IsInitialised(void) bool CUSBCECAdapterCommunication::StartBootloader(void) { - if (!IsRunning()) - return false; - - return m_commands->StartBootloader(); + return m_port->IsOpen() ? m_commands->StartBootloader() : false; } bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) { - return m_commands->SetAckMask(iMask); + return m_port->IsOpen() ? m_commands->SetAckMask(iMask) : false; } bool CUSBCECAdapterCommunication::PingAdapter(void) { - return m_commands->PingAdapter(); + return m_port->IsOpen() ? m_commands->PingAdapter() : false; } uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void) @@ -467,14 +476,19 @@ uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void) return m_commands->GetFirmwareVersion(); } +uint32_t CUSBCECAdapterCommunication::GetFirmwareBuildDate(void) +{ + return m_commands->RequestBuildDate(); +} + bool CUSBCECAdapterCommunication::PersistConfiguration(libcec_configuration *configuration) { - return m_commands->PersistConfiguration(configuration); + return m_port->IsOpen() ? m_commands->PersistConfiguration(configuration) : false; } bool CUSBCECAdapterCommunication::GetConfiguration(libcec_configuration *configuration) { - return m_commands->GetConfiguration(configuration); + return m_port->IsOpen() ? m_commands->GetConfiguration(configuration) : false; } CStdString CUSBCECAdapterCommunication::GetPortName(void) @@ -484,7 +498,7 @@ CStdString CUSBCECAdapterCommunication::GetPortName(void) bool CUSBCECAdapterCommunication::SetControlledMode(bool controlled) { - return m_commands->SetControlledMode(controlled); + return m_port->IsOpen() ? m_commands->SetControlledMode(controlled) : false; } void *CAdapterPingThread::Process(void) @@ -503,8 +517,8 @@ void *CAdapterPingThread::Process(void) { if (!m_com->PingAdapter()) { - /* sleep 1 second and retry */ - Sleep(1000); + /* sleep and retry */ + Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); ++iFailedCounter; } else