m_messageProcessor(NULL),
m_bInitialised(false)
{
+ for (unsigned int iPtr = 0; iPtr < 15; iPtr++)
+ m_bWaitingForAck[iPtr] = false;
m_port = new CSerialPort(strPort, iBaudRate);
}
{
//clear any input bytes
uint8_t buff[1024];
- while (m_port->Read(buff, 1024, 100) > 0)
+ ssize_t iBytesRead(0);
+ bool bGotMsgStart(false), bGotMsgEnd(false);
+ while ((iBytesRead = m_port->Read(buff, 1024, 100)) > 0 || (bGotMsgStart && !bGotMsgEnd))
{
- CLibCEC::AddLog(CEC_LOG_DEBUG, "data received, clearing it");
+ if (!bGotMsgStart)
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "data received, clearing it");
+ // if something was received, wait for MSGEND
+ for (ssize_t iPtr = 0; iPtr < iBytesRead; iPtr++)
+ {
+ if (buff[iPtr] == MSGSTART)
+ bGotMsgStart = true;
+ else if (buff[iPtr] == MSGEND)
+ bGotMsgEnd = true;
+ }
Sleep(250);
}
}
output->retryTimeout = iRetryLineTimeout;
output->tries = 0;
+ {
+ CLockObject lock(m_mutex);
+ m_bWaitingForAck[data.destination] = true;
+ }
+
bool bRetry(true);
while (bRetry && ++output->tries < output->maxTries)
{
}
if (m_currentframe.ack == 0x1)
{
- m_lastInitiator = m_currentframe.initiator;
- m_processor->HandlePoll(m_currentframe.initiator, m_currentframe.destination);
+ m_lastInitiator = m_currentframe.initiator;
+ if (!m_bWaitingForAck[m_currentframe.destination])
+ {
+ m_currentframe.eom = 1;
+ bEom = true;
+ }
+ else
+ {
+ m_bWaitingForAck[m_currentframe.destination] = false;
+ }
}
}
break;
}
CLibCEC::AddLog(bIsError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString());
- return msg.IsEOM();
+ return msg.IsEOM() || bEom;
}
uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void)
bool CUSBCECAdapterCommunication::SetSettingPhysicalAddress(uint16_t iPhysicalAddress)
{
CLockObject lock(m_mutex);
- CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the physical address to %2X", iPhysicalAddress);
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the physical address to %04X", iPhysicalAddress);
CCECAdapterMessage params;
params.PushEscaped(iPhysicalAddress >> 8);
if (msg.Message() == MSGCODE_FRAME_START && msg.IsACK())
{
- m_processor->HandlePoll(msg.Initiator(), msg.Destination());
- m_lastInitiator = msg.Initiator();
+ if (m_bWaitingForAck[msg.Initiator()])
+ m_bWaitingForAck[msg.Initiator()] = false;
+ else
+ {
+ m_processor->HandlePoll(msg.Initiator(), msg.Destination());
+ m_lastInitiator = msg.Initiator();
+ }
iNow = GetTimeMs();
continue;
}
return strName;
}
-bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, CCECAdapterMessage ¶ms, bool bExpectAck /* = true */, bool bIsTransmission /* = false */, bool bSendDirectly /* = true */)
+bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, CCECAdapterMessage ¶ms, bool bExpectAck /* = true */, bool bIsTransmission /* = false */, bool bSendDirectly /* = true */, bool bIsRetry /* = false */)
{
CLockObject lock(m_mutex);
{
CLibCEC::AddLog(CEC_LOG_ERROR, "'%s' failed", CCECAdapterMessage::ToString(msgCode));
delete output;
+
+ if (!bIsRetry && output->reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
+ {
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "setting controlled mode and retrying");
+ if (SetControlledMode(true))
+ return SendCommand(msgCode, params, bExpectAck, bIsTransmission, bSendDirectly, true);
+ }
return false;
}