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),
void CUSBCECAdapterCommunication::Close(void)
{
- SetAckMask(0);
- CLockObject lock(m_mutex);
- m_rcvCondition.Broadcast();
StopThread();
}
}
}
+ /* 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)
{
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))
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)
}
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);
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;
m_currentAdapterMessage.Clear();
m_bGotStart = false;
m_bNextIsEscaped = false;
+ m_bHasData = true;
m_rcvCondition.Signal();
}
else if (m_bNextIsEscaped)
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)
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
CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack");
}
}
- msg->condition.Signal();
+ msg->event.Signal();
}
void CUSBCECAdapterCommunication::WriteNextCommand(void)
if (m_outBuffer.Pop(msg))
SendMessageToAdapter(msg);
}
+
+CStdString CUSBCECAdapterCommunication::GetPortName(void)
+{
+ CStdString strName;
+ strName = m_port->GetName();
+ return strName;
+}