X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fadapter%2FUSBCECAdapterCommunication.cpp;h=6c548b00ad2eab495083b57ed76295c290b1d71d;hb=5daed059e1d5bca3ddfa0787679ef4e7b349e382;hp=b53114ceacd744b87302d450c06436eb8e877191;hpb=0b71487197ed7281dda06f53ecaf846f1fd7e942;p=deb_libcec.git diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index b53114c..6c548b0 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -44,7 +44,12 @@ using namespace PLATFORM; #define CEC_ADAPTER_PING_TIMEOUT 15000 -CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = 38400 */) : +// firmware version 2 +#define CEC_LATEST_ADAPTER_FW_VERSION 2 +// firmware date Thu Apr 26 20:14:49 2012 +0000 +#define CEC_LATEST_ADAPTER_FW_DATE 0x4F99ACB9 + +CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = CEC_SERIAL_DEFAULT_BAUDRATE */) : IAdapterCommunication(callback), m_port(NULL), m_iLineTimeout(0), @@ -54,7 +59,7 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCa m_commands(NULL), m_adapterMessageQueue(NULL) { - for (unsigned int iPtr = 0; iPtr < 15; iPtr++) + for (unsigned int iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++) m_bWaitingForAck[iPtr] = false; m_port = new CSerialPort(strPort, iBaudRate); } @@ -67,7 +72,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 +97,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; @@ -166,6 +174,8 @@ void CUSBCECAdapterCommunication::Close(void) SetControlledMode(false); } + m_adapterMessageQueue->Clear(); + /* stop and delete the ping thread */ if (m_pingThread) m_pingThread->StopThread(0); @@ -193,9 +203,7 @@ cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command & /* send the message */ bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0; - if (output->state == ADAPTER_MESSAGE_STATE_ERROR) - Close(); - else if (bRetry) + if (bRetry) Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT); retVal = output->state; @@ -263,7 +271,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]; @@ -312,6 +320,7 @@ bool CUSBCECAdapterCommunication::WriteToDevice(CCECAdapterMessage *message) { 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; } @@ -332,15 +341,19 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize CLockObject lock(m_mutex); 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()); - Close(); return false; - } else if (iBytesRead > 0) { /* add the data to the current frame */ @@ -372,7 +385,8 @@ CCECAdapterMessage *CUSBCECAdapterCommunication::SendCommand(cec_adapter_message } 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 +401,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 +431,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,7 +463,12 @@ bool CUSBCECAdapterCommunication::IsInitialised(void) bool CUSBCECAdapterCommunication::StartBootloader(void) { - return m_port->IsOpen() ? m_commands->StartBootloader() : false; + if (m_port->IsOpen() && m_commands->StartBootloader()) + { + Close(); + return true; + } + return false; } bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) @@ -464,6 +486,17 @@ uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void) return m_commands->GetFirmwareVersion(); } +uint32_t CUSBCECAdapterCommunication::GetFirmwareBuildDate(void) +{ + return m_commands->RequestBuildDate(); +} + +bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void) +{ + return GetFirmwareVersion() >= CEC_LATEST_ADAPTER_FW_VERSION && + GetFirmwareBuildDate() >= CEC_LATEST_ADAPTER_FW_DATE; +} + bool CUSBCECAdapterCommunication::PersistConfiguration(libcec_configuration *configuration) { return m_port->IsOpen() ? m_commands->PersistConfiguration(configuration) : false; @@ -500,8 +533,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