X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fadapter%2FUSBCECAdapterCommunication.cpp;h=80670e42f5c981f01bb2b1aff2c2d6c0fec345f6;hb=9ceaabcd6eabe161b36056153c5513ab95be29a8;hp=924c65a8b0a872ac29cdebc106e5b88f42f08817;hpb=9f68cc28b0e8e5d9caca7194a1ec53a78fa26d27;p=deb_libcec.git diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index 924c65a..80670e4 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -40,14 +40,34 @@ using namespace std; using namespace CEC; using namespace PLATFORM; +void *CUSBCECAdapterProcessor::Process(void) +{ + cec_command command; + while (!IsStopped()) + { + if (m_inBuffer.Pop(command)) + m_callback->OnCommandReceived(command); + Sleep(5); + } + + return NULL; +} + +void CUSBCECAdapterProcessor::AddCommand(cec_command command) +{ + m_inBuffer.Push(command); +} + CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate /* = 38400 */) : m_port(NULL), m_processor(processor), + m_bHasData(false), m_iLineTimeout(0), m_iFirmwareVersion(CEC_FW_VERSION_UNKNOWN), m_lastInitiator(CECDEVICE_UNKNOWN), m_bNextIsEscaped(false), - m_bGotStart(false) + m_bGotStart(false), + m_messageProcessor(NULL) { m_port = new PLATFORM::CSerialPort(strPort, iBaudRate); } @@ -172,14 +192,16 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32 void CUSBCECAdapterCommunication::Close(void) { - CLockObject lock(m_mutex); - m_rcvCondition.Broadcast(); StopThread(); } void *CUSBCECAdapterCommunication::Process(void) { + m_messageProcessor = new CUSBCECAdapterProcessor(m_callback); + m_messageProcessor->CreateThread(); + cec_command command; + command.Clear(); bool bCommandReceived(false); while (!IsStopped()) { @@ -191,7 +213,7 @@ void *CUSBCECAdapterCommunication::Process(void) /* push the next command to the callback method if there is one */ if (!IsStopped() && bCommandReceived) - m_callback->OnCommandReceived(command); + m_messageProcessor->AddCommand(command); if (!IsStopped()) { @@ -200,9 +222,17 @@ void *CUSBCECAdapterCommunication::Process(void) } } + /* stop the message processor */ + m_messageProcessor->StopThread(); + delete m_messageProcessor; + + /* notify all threads that are waiting on messages to be sent */ CCECAdapterMessage *msg(NULL); - if (m_outBuffer.Pop(msg)) - msg->condition.Broadcast(); + while (m_outBuffer.Pop(msg)) + msg->event.Broadcast(); + + /* set the ackmask to 0 before closing the connection */ + SetAckMaskInternal(0, true); if (m_port) { @@ -246,10 +276,9 @@ cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command & bool CUSBCECAdapterCommunication::Write(CCECAdapterMessage *data) { - CLockObject lock(data->mutex); data->state = ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT; m_outBuffer.Push(data); - data->condition.Wait(data->mutex); + data->event.Wait(5000); if ((data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT_ACKED) || (!data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT)) @@ -288,9 +317,10 @@ bool CUSBCECAdapterCommunication::Read(CCECAdapterMessage &msg, uint32_t iTimeou if (!m_inBuffer.Pop(buf)) { - if (iTimeout == 0 || !m_rcvCondition.Wait(m_mutex, iTimeout)) + if (iTimeout == 0 || !m_rcvCondition.Wait(m_mutex, m_bHasData, iTimeout)) return false; m_inBuffer.Pop(buf); + m_bHasData = m_inBuffer.Size() > 0; } if (buf) @@ -361,6 +391,7 @@ bool CUSBCECAdapterCommunication::ParseMessage(const CCECAdapterMessage &msg) if (msg.IsEmpty()) return bEom; + CLockObject adapterLock(m_mutex); switch(msg.Message()) { case MSGCODE_FRAME_START: @@ -407,13 +438,13 @@ bool CUSBCECAdapterCommunication::ParseMessage(const CCECAdapterMessage &msg) uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void) { - CLockObject lock(m_mutex); uint16_t iReturn(m_iFirmwareVersion); if (!IsRunning()) return iReturn; if (iReturn == CEC_FW_VERSION_UNKNOWN) { + CLockObject lock(m_mutex); CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting the firmware version"); CCECAdapterMessage *output = new CCECAdapterMessage; @@ -480,6 +511,11 @@ bool CUSBCECAdapterCommunication::SetLineTimeout(uint8_t iTimeout) } bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) +{ + return SetAckMaskInternal(iMask, false); +} + +bool CUSBCECAdapterCommunication::SetAckMaskInternal(uint16_t iMask, bool bWriteDirectly /* = false */) { bool bReturn(false); CLibCEC::AddLog(CEC_LOG_DEBUG, "setting ackmask to %2x", iMask); @@ -493,7 +529,9 @@ bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) output->PushBack(MSGEND); output->isTransmission = false; - if ((bReturn = Write(output)) == false) + if (bWriteDirectly) + SendMessageToAdapter(output); + else if ((bReturn = Write(output)) == false) CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the ackmask"); delete output; @@ -625,7 +663,8 @@ void CUSBCECAdapterCommunication::AddData(uint8_t *data, size_t iLen) m_currentAdapterMessage.Clear(); m_bGotStart = false; m_bNextIsEscaped = false; - m_rcvCondition.Signal(); + m_bHasData = true; + m_rcvCondition.Broadcast(); } else if (m_bNextIsEscaped) { @@ -657,6 +696,7 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize 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) @@ -670,7 +710,13 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize void CUSBCECAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg) { CLockObject adapterLock(m_mutex); - CLockObject lock(msg->mutex); + if (!m_port->IsOpen()) + { + CLibCEC::AddLog(CEC_LOG_ERROR, "error writing to serial port: the connection is closed"); + msg->state = ADAPTER_MESSAGE_STATE_ERROR; + return; + } + if (msg->tries == 1) SetLineTimeout(msg->lineTimeout); else @@ -692,7 +738,7 @@ void CUSBCECAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg) CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack"); } } - msg->condition.Signal(); + msg->event.Signal(); } void CUSBCECAdapterCommunication::WriteNextCommand(void) @@ -701,3 +747,10 @@ void CUSBCECAdapterCommunication::WriteNextCommand(void) if (m_outBuffer.Pop(msg)) SendMessageToAdapter(msg); } + +CStdString CUSBCECAdapterCommunication::GetPortName(void) +{ + CStdString strName; + strName = m_port->GetName(); + return strName; +}