m_bHasData(false),
m_iLineTimeout(0),
m_iFirmwareVersion(CEC_FW_VERSION_UNKNOWN),
- m_lastInitiator(CECDEVICE_UNKNOWN),
+ m_lastDestination(CECDEVICE_UNKNOWN),
m_bNextIsEscaped(false),
m_bGotStart(false),
m_messageProcessor(NULL),
m_port = new CSerialPort(strPort, iBaudRate);
}
-CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void)
-{
- Close();
-}
-
bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = 10000 */)
{
bool bReturn(false);
return bReturn;
}
-bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32_t iTimeoutMs /* = 10000 */, bool bSkipChecks /* = false */)
+bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32_t iTimeoutMs /* = 10000 */, bool bSkipChecks /* = false */, bool bStartListening /* = true */)
{
uint64_t iNow = GetTimeMs();
uint64_t iTimeout = iNow + iTimeoutMs;
if (!bSkipChecks && !CheckAdapter())
{
CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter failed to pass basic checks");
+ delete m_port;
+ m_port = NULL;
return false;
}
- else
+ else if (bStartListening)
{
if (CreateThread())
{
}
else
{
+ delete m_port;
+ m_port = NULL;
CLibCEC::AddLog(CEC_LOG_ERROR, "could not create a communication thread");
+ return false;
}
}
+ else
+ {
+ delete m_port;
+ m_port = NULL;
+ }
- return false;
+ return true;
}
void CUSBCECAdapterCommunication::Close(void)
{
- StopThread();
+ StopThread(0);
}
void *CUSBCECAdapterCommunication::Process(void)
/* stop the message processor */
m_messageProcessor->StopThread();
delete m_messageProcessor;
+ m_messageProcessor = NULL;
/* notify all threads that are waiting on messages to be sent */
CCECAdapterMessage *msg(NULL);
m_port = NULL;
}
+ m_rcvCondition.Broadcast();
return NULL;
}
output->retryTimeout = iRetryLineTimeout;
output->tries = 0;
+ if (data.destination < 15)
{
CLockObject lock(m_mutex);
m_bWaitingForAck[data.destination] = true;
}
if (m_currentframe.ack == 0x1)
{
- m_lastInitiator = m_currentframe.initiator;
- if (!m_bWaitingForAck[m_currentframe.destination])
- {
- m_currentframe.eom = 1;
- bEom = true;
- }
- else
+ m_lastDestination = m_currentframe.destination;
+ if (m_currentframe.destination < 15)
{
- m_bWaitingForAck[m_currentframe.destination] = false;
+ if (!m_bWaitingForAck[m_currentframe.destination])
+ m_processor->HandlePoll(m_currentframe.initiator, m_currentframe.destination);
+ else
+ m_bWaitingForAck[m_currentframe.destination] = false;
}
}
}
case MSGCODE_RECEIVE_FAILED:
{
m_currentframe.Clear();
- if (m_lastInitiator != CECDEVICE_UNKNOWN)
- bIsError = m_processor->HandleReceiveFailed(m_lastInitiator);
+ if (m_lastDestination != CECDEVICE_UNKNOWN)
+ bIsError = m_processor->HandleReceiveFailed(m_lastDestination);
}
break;
case MSGCODE_FRAME_DATA:
}
CLibCEC::AddLog(bIsError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString());
- return msg.IsEOM() || bEom;
+ return msg.IsEOM();
}
uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void)
bool CUSBCECAdapterCommunication::SetLineTimeout(uint8_t iTimeout)
{
- m_iLineTimeout = iTimeout;
- bool bReturn(m_iLineTimeout != iTimeout);
+ bool bReturn(true);
- if (!bReturn)
+ if (m_iLineTimeout != iTimeout)
{
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the line timeout to %d", iTimeout);
CCECAdapterMessage params;
params.PushEscaped(iTimeout);
bReturn = SendCommand(MSGCODE_TRANSMIT_IDLETIME, params);
+ if (bReturn)
+ m_iLineTimeout = iTimeout;
}
return bReturn;
bool CUSBCECAdapterCommunication::GetConfiguration(libcec_configuration *configuration)
{
+ configuration->iFirmwareVersion = m_iFirmwareVersion;
if (m_iFirmwareVersion < 2)
return false;
if (msg.Message() == MSGCODE_FRAME_START && msg.IsACK())
{
- if (m_bWaitingForAck[msg.Initiator()])
+ if (msg.Initiator() < 15 && m_bWaitingForAck[msg.Initiator()])
m_bWaitingForAck[msg.Initiator()] = false;
- else
+ else if (msg.Initiator() < 15)
{
m_processor->HandlePoll(msg.Initiator(), msg.Destination());
- m_lastInitiator = msg.Initiator();
+ m_lastDestination = msg.Initiator();
}
iNow = GetTimeMs();
continue;
}
if (msg.Message() == MSGCODE_RECEIVE_FAILED &&
- m_lastInitiator != CECDEVICE_UNKNOWN &&
- m_processor->HandleReceiveFailed(m_lastInitiator))
+ m_lastDestination != CECDEVICE_UNKNOWN &&
+ m_processor->HandleReceiveFailed(m_lastDestination))
{
iNow = GetTimeMs();
continue;
Write(output);
bool bWriteOk = output->state == (output->expectControllerAck ? ADAPTER_MESSAGE_STATE_SENT_ACKED : ADAPTER_MESSAGE_STATE_SENT);
+ cec_adapter_messagecode reply = output->reply;
+ delete output;
+
if (!bWriteOk)
{
CLibCEC::AddLog(CEC_LOG_ERROR, "'%s' failed", CCECAdapterMessage::ToString(msgCode));
- delete output;
- if (!bIsRetry && output->reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
+ if (!bIsRetry && reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
{
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting controlled mode and retrying");
if (SetControlledMode(true))
return false;
}
- delete output;
return true;
}